elements_miniscript/descriptor/
mod.rs

1// Written in 2018 by Andrew Poelstra <apoelstra@wpsoftware.net>
2// SPDX-License-Identifier: CC0-1.0
3
4//! # Output Descriptors
5//!
6//! Tools for representing Bitcoin output's scriptPubKeys as abstract spending
7//! policies known as "output descriptors". These include a Miniscript which
8//! describes the actual signing policy, as well as the blockchain format (P2SH,
9//! Segwit v0, etc.)
10//!
11//! The format represents EC public keys abstractly to allow wallets to replace
12//! these with BIP32 paths, pay-to-contract instructions, etc.
13//!
14
15use std::collections::HashMap;
16use std::fmt;
17use std::ops::Range;
18use std::str::{self, FromStr};
19use std::sync::Arc;
20
21pub mod pegin;
22
23use bitcoin::WitnessVersion;
24use elements::hashes::{hash160, ripemd160, sha256};
25use elements::{secp256k1_zkp as secp256k1, secp256k1_zkp, Script, TxIn};
26use {bitcoin, elements};
27
28use self::checksum::verify_checksum;
29use crate::extensions::{CovExtArgs, ExtParam, ParseableExt};
30use crate::miniscript::{Legacy, Miniscript, Segwitv0};
31use crate::{
32    expression, hash256, miniscript, BareCtx, CovenantExt, Error, ExtTranslator, Extension,
33    ForEachKey, MiniscriptKey, NoExt, Satisfier, ToPublicKey, TranslateExt, TranslatePk,
34    Translator,
35};
36
37mod bare;
38mod csfs_cov;
39mod segwitv0;
40mod sh;
41mod sortedmulti;
42mod tr;
43
44// Descriptor Exports
45pub use self::bare::{Bare, Pkh};
46pub use self::segwitv0::{Wpkh, Wsh, WshInner};
47pub use self::sh::{Sh, ShInner};
48pub use self::sortedmulti::SortedMultiVec;
49
50pub mod checksum;
51mod key;
52pub use self::csfs_cov::{CovError, CovOperations, LegacyCSFSCov, LegacyCovSatisfier};
53pub(crate) use self::key::maybe_fmt_master_id;
54pub use self::key::{
55    ConversionError, DefiniteDescriptorKey, DerivPaths, DescriptorKeyParseError,
56    DescriptorMultiXKey, DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey, InnerXKey,
57    SinglePriv, SinglePub, SinglePubKey, Wildcard,
58};
59pub use self::tr::{TapLeafScript, TapTree, Tr};
60/// Alias type for a map of public key to secret key
61///
62/// This map is returned whenever a descriptor that contains secrets is parsed using
63/// [`Descriptor::parse_descriptor`], since the descriptor will always only contain
64/// public keys. This map allows looking up the corresponding secret key given a
65/// public key from the descriptor.
66pub type KeyMap = HashMap<DescriptorPublicKey, DescriptorSecretKey>;
67
68/// Elements Descriptor String Prefix
69pub const ELMTS_STR: &str = "el";
70
71/// Descriptor Type of the descriptor
72#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
73pub enum DescriptorType {
74    /// Bare descriptor(Contains the native P2pk)
75    Bare,
76    /// Pure Sh Descriptor. Does not contain nested Wsh/Wpkh
77    Sh,
78    /// Pkh Descriptor
79    Pkh,
80    /// Wpkh Descriptor
81    Wpkh,
82    /// Wsh
83    Wsh,
84    /// Sh Wrapped Wsh
85    ShWsh,
86    /// Sh wrapped Wpkh
87    ShWpkh,
88    /// Sh Sorted Multi
89    ShSortedMulti,
90    /// Wsh Sorted Multi
91    WshSortedMulti,
92    /// Sh Wsh Sorted Multi
93    ShWshSortedMulti,
94    /// Legacy Pegin
95    LegacyPegin,
96    /// Dynafed Pegin
97    Pegin,
98    /// Covenant: Only supported in p2wsh context
99    Cov,
100    /// Tr
101    Tr,
102}
103
104impl fmt::Display for DescriptorType {
105    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106        match *self {
107            DescriptorType::Bare => write!(f, "bare"),
108            DescriptorType::Sh => write!(f, "sh"),
109            DescriptorType::Pkh => write!(f, "pkh"),
110            DescriptorType::Wpkh => write!(f, "wpkh"),
111            DescriptorType::Wsh => write!(f, "wsh"),
112            DescriptorType::ShWsh => write!(f, "shwsh"),
113            DescriptorType::ShWpkh => write!(f, "shwpkh"),
114            DescriptorType::ShSortedMulti => write!(f, "shsortedmulti"),
115            DescriptorType::WshSortedMulti => write!(f, "wshsortedmulti"),
116            DescriptorType::ShWshSortedMulti => write!(f, "shwshsortedmulti"),
117            DescriptorType::LegacyPegin => write!(f, "legacy_pegin"),
118            DescriptorType::Pegin => write!(f, "pegin"),
119            DescriptorType::Cov => write!(f, "elcovwsh"),
120            DescriptorType::Tr => write!(f, "tr"),
121        }
122    }
123}
124impl FromStr for DescriptorType {
125    type Err = Error;
126
127    /// Does not check if the Descriptor is well formed or not.
128    /// Such errors would be caught later while parsing the descriptor
129    fn from_str(s: &str) -> Result<Self, Self::Err> {
130        if s.len() >= 12 && &s[0..12] == "legacy_pegin" {
131            Ok(DescriptorType::LegacyPegin)
132        } else if s.len() >= 5 && &s[0..5] == "pegin" {
133            Ok(DescriptorType::Pegin)
134        } else if s.len() >= 3 && &s[0..3] == "pkh" {
135            Ok(DescriptorType::Pkh)
136        } else if s.len() >= 4 && &s[0..4] == "wpkh" {
137            Ok(DescriptorType::Wpkh)
138        } else if s.len() >= 6 && &s[0..6] == "sh(wsh" {
139            Ok(DescriptorType::ShWsh)
140        } else if s.len() >= 7 && &s[0..7] == "sh(wpkh" {
141            Ok(DescriptorType::ShWpkh)
142        } else if s.len() >= 14 && &s[0..14] == "sh(sortedmulti" {
143            Ok(DescriptorType::ShSortedMulti)
144        } else if s.len() >= 18 && &s[0..18] == "sh(wsh(sortedmulti" {
145            Ok(DescriptorType::ShWshSortedMulti)
146        } else if s.len() >= 2 && &s[0..2] == "sh" {
147            Ok(DescriptorType::Sh)
148        } else if s.len() >= 15 && &s[0..15] == "wsh(sortedmulti" {
149            Ok(DescriptorType::WshSortedMulti)
150        } else if s.len() >= 3 && &s[0..3] == "wsh" {
151            Ok(DescriptorType::Wsh)
152        } else if s.len() >= 8 && &s[0..8] == "elcovwsh" {
153            Ok(DescriptorType::Cov)
154        } else {
155            Ok(DescriptorType::Bare)
156        }
157    }
158}
159/// Method for determining Type of descriptor when parsing from String
160pub enum DescriptorInfo {
161    /// Bitcoin Descriptor
162    Btc {
163        /// Whether descriptor has secret keys
164        has_secret: bool,
165        /// The type of descriptor
166        ty: DescriptorType,
167    },
168    /// Elements Descriptor
169    Elements {
170        /// Whether descriptor has secret keys
171        has_secret: bool,
172        /// The type of descriptor
173        ty: DescriptorType,
174    },
175    /// Pegin descriptor
176    /// Only provides information about the bitcoin side of descriptor
177    /// Use the corresponding [`pegin::LegacyPegin::into_user_descriptor`] or
178    /// [`pegin::Pegin::into_user_descriptor`] method to obtain the user descriptor.
179    /// and call DescriptorType method on it on to find information about
180    /// the user claim descriptor.
181    Pegin {
182        /// Whether the user descriptor has secret
183        has_secret: bool,
184        /// The type of descriptor
185        ty: DescriptorType,
186    },
187}
188
189impl DescriptorInfo {
190    /// Compute the [`DescriptorInfo`] for the given descriptor string
191    /// This method should when the user is unsure whether they are parsing
192    /// Bitcoin Descriptor, Elements Descriptor or Pegin Descriptors.
193    /// This also returns information whether the descriptor contains any secrets
194    /// of the type [`DescriptorSecretKey`]. If the descriptor contains secret, users
195    /// should use the method [`Descriptor::parse_descriptor`] to obtain the
196    /// Descriptor and a secret key to public key mapping
197    pub fn from_desc_str<T: Extension>(s: &str) -> Result<Self, Error> {
198        // Parse as a string descriptor
199        let descriptor = Descriptor::<String, T>::from_str(s)?;
200        let has_secret = descriptor.for_any_key(|pk| DescriptorSecretKey::from_str(pk).is_ok());
201        let ty = DescriptorType::from_str(s)?;
202        let is_pegin = matches!(ty, DescriptorType::Pegin | DescriptorType::LegacyPegin);
203        // Todo: add elements later
204        if is_pegin {
205            Ok(DescriptorInfo::Pegin { has_secret, ty })
206        } else {
207            Ok(DescriptorInfo::Btc { has_secret, ty })
208        }
209    }
210}
211
212/// Script descriptor
213#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
214pub enum Descriptor<Pk: MiniscriptKey, T: Extension = CovenantExt<CovExtArgs>> {
215    /// A raw scriptpubkey (including pay-to-pubkey) under Legacy context
216    Bare(Bare<Pk>),
217    /// Pay-to-PubKey-Hash
218    Pkh(Pkh<Pk>),
219    /// Pay-to-Witness-PubKey-Hash
220    Wpkh(Wpkh<Pk>),
221    /// Pay-to-ScriptHash(includes nested wsh/wpkh/sorted multi)
222    Sh(Sh<Pk>),
223    /// Pay-to-Witness-ScriptHash with Segwitv0 context
224    Wsh(Wsh<Pk>),
225    /// Pay-to-Taproot
226    Tr(Tr<Pk, NoExt>),
227    /// Pay-to-Taproot
228    TrExt(Tr<Pk, T>),
229    /// Covenant descriptor with all known extensions
230    /// Downstream implementations of extensions should implement directly use descriptor API
231    LegacyCSFSCov(LegacyCSFSCov<Pk, T>),
232}
233
234impl<Pk: MiniscriptKey, Ext: Extension> From<Bare<Pk>> for Descriptor<Pk, Ext> {
235    #[inline]
236    fn from(inner: Bare<Pk>) -> Self {
237        Descriptor::Bare(inner)
238    }
239}
240
241impl<Pk: MiniscriptKey, Ext: Extension> From<Pkh<Pk>> for Descriptor<Pk, Ext> {
242    #[inline]
243    fn from(inner: Pkh<Pk>) -> Self {
244        Descriptor::Pkh(inner)
245    }
246}
247
248impl<Pk: MiniscriptKey, Ext: Extension> From<Wpkh<Pk>> for Descriptor<Pk, Ext> {
249    #[inline]
250    fn from(inner: Wpkh<Pk>) -> Self {
251        Descriptor::Wpkh(inner)
252    }
253}
254
255impl<Pk: MiniscriptKey, Ext: Extension> From<Sh<Pk>> for Descriptor<Pk, Ext> {
256    #[inline]
257    fn from(inner: Sh<Pk>) -> Self {
258        Descriptor::Sh(inner)
259    }
260}
261
262impl<Pk: MiniscriptKey, Ext: Extension> From<Wsh<Pk>> for Descriptor<Pk, Ext> {
263    #[inline]
264    fn from(inner: Wsh<Pk>) -> Self {
265        Descriptor::Wsh(inner)
266    }
267}
268
269impl<Pk: MiniscriptKey, Ext: Extension> From<Tr<Pk, NoExt>> for Descriptor<Pk, Ext> {
270    #[inline]
271    fn from(inner: Tr<Pk, NoExt>) -> Self {
272        Descriptor::Tr(inner)
273    }
274}
275
276impl<Pk: MiniscriptKey, Arg: ExtParam> From<LegacyCSFSCov<Pk, CovenantExt<Arg>>>
277    for Descriptor<Pk, CovenantExt<Arg>>
278{
279    #[inline]
280    fn from(inner: LegacyCSFSCov<Pk, CovenantExt<Arg>>) -> Self {
281        Descriptor::LegacyCSFSCov(inner)
282    }
283}
284
285impl DescriptorType {
286    /// Returns the segwit version implied by the descriptor type.
287    ///
288    /// This will return `Some(WitnessVersion::V0)` whether it is "native" segwitv0 or "wrapped" p2sh segwit.
289    pub fn segwit_version(&self) -> Option<WitnessVersion> {
290        use self::DescriptorType::*;
291        match self {
292            Tr => Some(WitnessVersion::V1),
293            Wpkh | ShWpkh | Wsh | ShWsh | ShWshSortedMulti | WshSortedMulti => {
294                Some(WitnessVersion::V0)
295            }
296            Bare | Sh | Pkh | ShSortedMulti => None,
297            LegacyPegin => Some(WitnessVersion::V1),
298            Pegin => None, // Can have any witness version
299            Cov => None,   // Can have any witness version
300        }
301    }
302}
303
304impl<Pk: MiniscriptKey, Ext: Extension> Descriptor<Pk, Ext> {
305    // Keys
306
307    /// Create a new pk descriptor
308    pub fn new_pk(pk: Pk) -> Self {
309        // roundabout way to constuct `c:pk_k(pk)`
310        let ms: Miniscript<Pk, BareCtx> =
311            Miniscript::from_ast(miniscript::decode::Terminal::Check(Arc::new(
312                Miniscript::from_ast(miniscript::decode::Terminal::PkK(pk))
313                    .expect("Type check cannot fail"),
314            )))
315            .expect("Type check cannot fail");
316        Descriptor::Bare(Bare::new(ms).expect("Context checks cannot fail for p2pk"))
317    }
318
319    /// Create a new PkH descriptor
320    pub fn new_pkh(pk: Pk) -> Self {
321        Descriptor::Pkh(Pkh::new(pk))
322    }
323
324    /// Create a new Wpkh descriptor
325    /// Will return Err if uncompressed key is used
326    pub fn new_wpkh(pk: Pk) -> Result<Self, Error> {
327        Ok(Descriptor::Wpkh(Wpkh::new(pk)?))
328    }
329
330    /// Create a new sh wrapped wpkh from `Pk`.
331    /// Errors when uncompressed keys are supplied
332    pub fn new_sh_wpkh(pk: Pk) -> Result<Self, Error> {
333        Ok(Descriptor::Sh(Sh::new_wpkh(pk)?))
334    }
335
336    // Miniscripts
337
338    /// Create a new sh for a given redeem script
339    /// Errors when miniscript exceeds resource limits under p2sh context
340    /// or does not type check at the top level
341    pub fn new_sh(ms: Miniscript<Pk, Legacy>) -> Result<Self, Error> {
342        Ok(Descriptor::Sh(Sh::new(ms)?))
343    }
344
345    /// Create a new wsh descriptor from witness script
346    /// Errors when miniscript exceeds resource limits under p2sh context
347    /// or does not type check at the top level
348    pub fn new_wsh(ms: Miniscript<Pk, Segwitv0>) -> Result<Self, Error> {
349        Ok(Descriptor::Wsh(Wsh::new(ms)?))
350    }
351
352    /// Create a new sh wrapped wsh descriptor with witness script
353    /// Errors when miniscript exceeds resource limits under wsh context
354    /// or does not type check at the top level
355    pub fn new_sh_wsh(ms: Miniscript<Pk, Segwitv0>) -> Result<Self, Error> {
356        Ok(Descriptor::Sh(Sh::new_wsh(ms)?))
357    }
358
359    /// Create a new bare descriptor from witness script
360    /// Errors when miniscript exceeds resource limits under bare context
361    /// or does not type check at the top level
362    pub fn new_bare(ms: Miniscript<Pk, BareCtx>) -> Result<Self, Error> {
363        Ok(Descriptor::Bare(Bare::new(ms)?))
364    }
365
366    // Wrap with sh
367
368    /// Create a new sh wrapper for the given wpkh descriptor
369    pub fn new_sh_with_wpkh(wpkh: Wpkh<Pk>) -> Self {
370        Descriptor::Sh(Sh::new_with_wpkh(wpkh))
371    }
372
373    /// Create a new sh wrapper for the given wsh descriptor
374    pub fn new_sh_with_wsh(wsh: Wsh<Pk>) -> Self {
375        Descriptor::Sh(Sh::new_with_wsh(wsh))
376    }
377
378    // sorted multi
379
380    /// Create a new sh sortedmulti descriptor with threshold `k`
381    /// and Vec of `pks`.
382    /// Errors when miniscript exceeds resource limits under p2sh context
383    pub fn new_sh_sortedmulti(k: usize, pks: Vec<Pk>) -> Result<Self, Error> {
384        Ok(Descriptor::Sh(Sh::new_sortedmulti(k, pks)?))
385    }
386
387    /// Create a new sh wrapped wsh sortedmulti descriptor from threshold
388    /// `k` and Vec of `pks`
389    /// Errors when miniscript exceeds resource limits under segwit context
390    pub fn new_sh_wsh_sortedmulti(k: usize, pks: Vec<Pk>) -> Result<Self, Error> {
391        Ok(Descriptor::Sh(Sh::new_wsh_sortedmulti(k, pks)?))
392    }
393
394    /// Create a new wsh sorted multi descriptor
395    /// Errors when miniscript exceeds resource limits under p2sh context
396    pub fn new_wsh_sortedmulti(k: usize, pks: Vec<Pk>) -> Result<Self, Error> {
397        Ok(Descriptor::Wsh(Wsh::new_sortedmulti(k, pks)?))
398    }
399
400    /// Create new tr descriptor
401    /// Errors when miniscript exceeds resource limits under Tap context
402    pub fn new_tr(key: Pk, script: Option<tr::TapTree<Pk, NoExt>>) -> Result<Self, Error> {
403        Ok(Descriptor::Tr(Tr::new(key, script)?))
404    }
405
406    /// Create new tr descriptor
407    /// Errors when miniscript exceeds resource limits under Tap context
408    pub fn new_tr_ext(key: Pk, script: Option<tr::TapTree<Pk, Ext>>) -> Result<Self, Error> {
409        Ok(Descriptor::TrExt(Tr::new(key, script)?))
410    }
411
412    /// Get the [DescriptorType] of [Descriptor]
413    pub fn desc_type(&self) -> DescriptorType {
414        match *self {
415            Descriptor::Bare(ref _bare) => DescriptorType::Bare,
416            Descriptor::Pkh(ref _pkh) => DescriptorType::Pkh,
417            Descriptor::Wpkh(ref _wpkh) => DescriptorType::Wpkh,
418            Descriptor::Sh(ref sh) => match sh.as_inner() {
419                ShInner::Wsh(ref wsh) => match wsh.as_inner() {
420                    WshInner::SortedMulti(ref _smv) => DescriptorType::ShWshSortedMulti,
421                    WshInner::Ms(ref _ms) => DescriptorType::ShWsh,
422                },
423                ShInner::Wpkh(ref _wpkh) => DescriptorType::ShWpkh,
424                ShInner::SortedMulti(ref _smv) => DescriptorType::ShSortedMulti,
425                ShInner::Ms(ref _ms) => DescriptorType::Sh,
426            },
427            Descriptor::Wsh(ref wsh) => match wsh.as_inner() {
428                WshInner::SortedMulti(ref _smv) => DescriptorType::WshSortedMulti,
429                WshInner::Ms(ref _ms) => DescriptorType::Wsh,
430            },
431            Descriptor::LegacyCSFSCov(ref _cov) => DescriptorType::Cov,
432            Descriptor::Tr(ref _tr) => DescriptorType::Tr,
433            Descriptor::TrExt(ref _tr) => DescriptorType::Tr,
434        }
435    }
436
437    /// Checks whether the descriptor is safe.
438    ///
439    /// Checks whether all the spend paths in the descriptor are possible on the
440    /// bitcoin network under the current standardness and consensus rules. Also
441    /// checks whether the descriptor requires signatures on all spend paths and
442    /// whether the script is malleable.
443    ///
444    /// In general, all the guarantees of miniscript hold only for safe scripts.
445    /// The signer may not be able to find satisfactions even if one exists.
446    pub fn sanity_check(&self) -> Result<(), Error> {
447        match *self {
448            Descriptor::Bare(ref bare) => bare.sanity_check(),
449            Descriptor::Pkh(_) => Ok(()),
450            Descriptor::Wpkh(ref wpkh) => wpkh.sanity_check(),
451            Descriptor::Wsh(ref wsh) => wsh.sanity_check(),
452            Descriptor::Sh(ref sh) => sh.sanity_check(),
453            Descriptor::LegacyCSFSCov(ref cov) => cov.sanity_check(),
454            Descriptor::Tr(ref tr) => tr.sanity_check(),
455            Descriptor::TrExt(ref tr) => tr.sanity_check(),
456        }
457    }
458
459    /// Computes an upper bound on the difference between a non-satisfied
460    /// `TxIn`'s `segwit_weight` and a satisfied `TxIn`'s `segwit_weight`
461    ///
462    /// Since this method uses `segwit_weight` instead of `legacy_weight`,
463    /// if you want to include only legacy inputs in your transaction,
464    /// you should remove 1WU from each input's `max_weight_to_satisfy`
465    /// for a more accurate estimate.
466    ///
467    /// In other words, for segwit inputs or legacy inputs included in
468    /// segwit transactions, the following will hold for each input if
469    /// that input was satisfied with the largest possible witness:
470    /// ```ignore
471    /// for i in 0..transaction.input.len() {
472    ///     assert_eq!(
473    ///         descriptor_for_input[i].max_weight_to_satisfy(),
474    ///         transaction.input[i].segwit_weight() - Txin::default().segwit_weight()
475    ///     );
476    /// }
477    /// ```
478    ///
479    /// Instead, for legacy transactions, the following will hold for each input
480    /// if that input was satisfied with the largest possible witness:
481    /// ```ignore
482    /// for i in 0..transaction.input.len() {
483    ///     assert_eq!(
484    ///         descriptor_for_input[i].max_weight_to_satisfy(),
485    ///         transaction.input[i].legacy_weight() - Txin::default().legacy_weight()
486    ///     );
487    /// }
488    /// ```
489    ///
490    /// Assumes all ECDSA signatures are 73 bytes, including push opcode and
491    /// sighash suffix.
492    /// Assumes all Schnorr signatures are 66 bytes, including push opcode and
493    /// sighash suffix.
494    ///
495    /// # Errors
496    /// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
497    pub fn max_weight_to_satisfy(&self) -> Result<usize, Error> {
498        let weight = match *self {
499            Descriptor::Bare(ref bare) => bare.max_weight_to_satisfy()?,
500            Descriptor::Pkh(ref pkh) => pkh.max_weight_to_satisfy(),
501            Descriptor::Wpkh(ref wpkh) => wpkh.max_weight_to_satisfy(),
502            Descriptor::Wsh(ref wsh) => wsh.max_weight_to_satisfy()?,
503            Descriptor::Sh(ref sh) => sh.max_weight_to_satisfy()?,
504            Descriptor::Tr(ref tr) => tr.max_weight_to_satisfy()?,
505            Descriptor::TrExt(ref tr) => tr.max_weight_to_satisfy()?,
506            Descriptor::LegacyCSFSCov(ref csfs) => csfs.max_satisfaction_weight()?,
507        };
508        Ok(weight)
509    }
510
511    /// Computes an upper bound on the weight of a satisfying witness to the
512    /// transaction.
513    ///
514    /// Assumes all ec-signatures are 73 bytes, including push opcode and
515    /// sighash suffix. Includes the weight of the VarInts encoding the
516    /// scriptSig and witness stack length.
517    ///
518    /// # Errors
519    /// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
520    #[deprecated(note = "use max_weight_to_satisfy instead")]
521    #[allow(deprecated)]
522    pub fn max_satisfaction_weight(&self) -> Result<usize, Error> {
523        let weight = match *self {
524            Descriptor::Bare(ref bare) => bare.max_satisfaction_weight()?,
525            Descriptor::Pkh(ref pkh) => pkh.max_satisfaction_weight(),
526            Descriptor::Wpkh(ref wpkh) => wpkh.max_satisfaction_weight(),
527            Descriptor::Wsh(ref wsh) => wsh.max_satisfaction_weight()?,
528            Descriptor::Sh(ref sh) => sh.max_satisfaction_weight()?,
529            Descriptor::LegacyCSFSCov(ref cov) => cov.max_satisfaction_weight()?,
530            Descriptor::Tr(ref tr) => tr.max_satisfaction_weight()?,
531            Descriptor::TrExt(ref tr) => tr.max_satisfaction_weight()?,
532        };
533        Ok(weight)
534    }
535}
536
537impl<Pk: MiniscriptKey, Arg: ExtParam> Descriptor<Pk, CovenantExt<Arg>> {
538    /// Create a new covenant descriptor
539    // All extensions are supported in wsh descriptor
540    pub fn new_cov_wsh(
541        pk: Pk,
542        ms: Miniscript<Pk, Segwitv0, CovenantExt<Arg>>,
543    ) -> Result<Self, Error> {
544        let cov = LegacyCSFSCov::new(pk, ms)?;
545        Ok(Descriptor::LegacyCSFSCov(cov))
546    }
547
548    /// Tries to convert descriptor as a covenant descriptor
549    pub fn as_cov(&self) -> Result<&LegacyCSFSCov<Pk, CovenantExt<Arg>>, Error> {
550        if let Descriptor::LegacyCSFSCov(cov) = self {
551            Ok(cov)
552        } else {
553            Err(Error::CovError(CovError::BadCovDescriptor))
554        }
555    }
556}
557
558impl<Pk: MiniscriptKey + ToPublicKey, Ext: Extension + ParseableExt> Descriptor<Pk, Ext> {
559    ///
560    /// Obtains the blinded address for this descriptor
561    ///
562    /// # Errors
563    /// For raw/bare descriptors that don't have an address.
564    //
565    // Note: The address kept is kept without the blinder to avoid more conflicts with upstream
566    pub fn blinded_address(
567        &self,
568        blinder: secp256k1_zkp::PublicKey,
569        params: &'static elements::AddressParams,
570    ) -> Result<elements::Address, Error>
571    where
572        Pk: ToPublicKey,
573    {
574        match *self {
575            Descriptor::Bare(_) => Err(Error::BareDescriptorAddr),
576            Descriptor::Pkh(ref pkh) => Ok(pkh.address(Some(blinder), params)),
577            Descriptor::Wpkh(ref wpkh) => Ok(wpkh.address(Some(blinder), params)),
578            Descriptor::Wsh(ref wsh) => Ok(wsh.address(Some(blinder), params)),
579            Descriptor::Sh(ref sh) => Ok(sh.address(Some(blinder), params)),
580            Descriptor::LegacyCSFSCov(ref cov) => Ok(cov.address(Some(blinder), params)),
581            Descriptor::Tr(ref tr) => Ok(tr.address(Some(blinder), params)),
582            Descriptor::TrExt(ref tr) => Ok(tr.address(Some(blinder), params)),
583        }
584    }
585
586    /// Obtains an address for this descriptor. For blinding see [`Descriptor::blinded_address`]
587    pub fn address(
588        &self,
589        params: &'static elements::AddressParams,
590    ) -> Result<elements::Address, Error>
591    where
592        Pk: ToPublicKey,
593    {
594        match *self {
595            Descriptor::Bare(_) => Err(Error::BareDescriptorAddr),
596            Descriptor::Pkh(ref pkh) => Ok(pkh.address(None, params)),
597            Descriptor::Wpkh(ref wpkh) => Ok(wpkh.address(None, params)),
598            Descriptor::Wsh(ref wsh) => Ok(wsh.address(None, params)),
599            Descriptor::Sh(ref sh) => Ok(sh.address(None, params)),
600            Descriptor::LegacyCSFSCov(ref cov) => Ok(cov.address(None, params)),
601            Descriptor::Tr(ref tr) => Ok(tr.address(None, params)),
602            Descriptor::TrExt(ref tr) => Ok(tr.address(None, params)),
603        }
604    }
605
606    /// Computes the scriptpubkey of the descriptor.
607    pub fn script_pubkey(&self) -> Script {
608        match *self {
609            Descriptor::Bare(ref bare) => bare.script_pubkey(),
610            Descriptor::Pkh(ref pkh) => pkh.script_pubkey(),
611            Descriptor::Wpkh(ref wpkh) => wpkh.script_pubkey(),
612            Descriptor::Wsh(ref wsh) => wsh.script_pubkey(),
613            Descriptor::Sh(ref sh) => sh.script_pubkey(),
614            Descriptor::LegacyCSFSCov(ref cov) => cov.script_pubkey(),
615            Descriptor::Tr(ref tr) => tr.script_pubkey(),
616            Descriptor::TrExt(ref tr) => tr.script_pubkey(),
617        }
618    }
619
620    /// Computes the scriptSig that will be in place for an unsigned input
621    /// spending an output with this descriptor. For pre-segwit descriptors,
622    /// which use the scriptSig for signatures, this returns the empty script.
623    ///
624    /// This is used in Segwit transactions to produce an unsigned transaction
625    /// whose txid will not change during signing (since only the witness data
626    /// will change).
627    pub fn unsigned_script_sig(&self) -> Script {
628        match *self {
629            Descriptor::Bare(_) => Script::new(),
630            Descriptor::Pkh(_) => Script::new(),
631            Descriptor::Wpkh(_) => Script::new(),
632            Descriptor::Wsh(_) => Script::new(),
633            Descriptor::Sh(ref sh) => sh.unsigned_script_sig(),
634            Descriptor::LegacyCSFSCov(_) => Script::new(),
635            Descriptor::Tr(_) => Script::new(),
636            Descriptor::TrExt(_) => Script::new(),
637        }
638    }
639
640    /// Computes the the underlying script before any hashing is done. For
641    /// `Bare`, `Pkh` and `Wpkh` this is the scriptPubkey; for `ShWpkh` and `Sh`
642    /// this is the redeemScript; for the others it is the witness script.
643    ///
644    /// # Errors
645    /// If the descriptor is a taproot descriptor.
646    pub fn explicit_script(&self) -> Result<Script, Error> {
647        match *self {
648            Descriptor::Bare(ref bare) => Ok(bare.script_pubkey()),
649            Descriptor::Pkh(ref pkh) => Ok(pkh.script_pubkey()),
650            Descriptor::Wpkh(ref wpkh) => Ok(wpkh.script_pubkey()),
651            Descriptor::Wsh(ref wsh) => Ok(wsh.inner_script()),
652            Descriptor::Sh(ref sh) => Ok(sh.inner_script()),
653            Descriptor::Tr(_) => Err(Error::TrNoScriptCode),
654            Descriptor::TrExt(_) => Err(Error::TrNoScriptCode),
655            Descriptor::LegacyCSFSCov(ref cov) => Ok(cov.inner_script()),
656        }
657    }
658
659    /// Computes the `scriptCode` of a transaction output.
660    ///
661    /// The `scriptCode` is the Script of the previous transaction output being
662    /// serialized in the sighash when evaluating a `CHECKSIG` & co. OP code.
663    ///
664    /// # Errors
665    /// If the descriptor is a taproot descriptor.
666    pub fn script_code(&self) -> Result<Script, Error> {
667        match *self {
668            Descriptor::Bare(ref bare) => Ok(bare.ecdsa_sighash_script_code()),
669            Descriptor::Pkh(ref pkh) => Ok(pkh.ecdsa_sighash_script_code()),
670            Descriptor::Wpkh(ref wpkh) => Ok(wpkh.ecdsa_sighash_script_code()),
671            Descriptor::Wsh(ref wsh) => Ok(wsh.ecdsa_sighash_script_code()),
672            Descriptor::Sh(ref sh) => Ok(sh.ecdsa_sighash_script_code()),
673            Descriptor::LegacyCSFSCov(ref cov) => Ok(cov.ecdsa_sighash_script_code()),
674            Descriptor::Tr(_) => Err(Error::TrNoScriptCode),
675            Descriptor::TrExt(_) => Err(Error::TrNoScriptCode),
676        }
677    }
678
679    /// Returns satisfying non-malleable witness and scriptSig to spend an
680    /// output controlled by the given descriptor if it possible to
681    /// construct one using the satisfier S.
682    pub fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
683    where
684        S: Satisfier<Pk>,
685    {
686        match *self {
687            Descriptor::Bare(ref bare) => bare.get_satisfaction(satisfier),
688            Descriptor::Pkh(ref pkh) => pkh.get_satisfaction(satisfier),
689            Descriptor::Wpkh(ref wpkh) => wpkh.get_satisfaction(satisfier),
690            Descriptor::Wsh(ref wsh) => wsh.get_satisfaction(satisfier),
691            Descriptor::Sh(ref sh) => sh.get_satisfaction(satisfier),
692            Descriptor::LegacyCSFSCov(ref cov) => cov.get_satisfaction(satisfier),
693            Descriptor::Tr(ref tr) => tr.get_satisfaction(satisfier),
694            Descriptor::TrExt(ref tr) => tr.get_satisfaction(satisfier),
695        }
696    }
697
698    /// Returns a possilbly mallable satisfying non-malleable witness and scriptSig to spend an
699    /// output controlled by the given descriptor if it possible to
700    /// construct one using the satisfier S.
701    pub fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, Script), Error>
702    where
703        S: Satisfier<Pk>,
704    {
705        match *self {
706            Descriptor::Bare(ref bare) => bare.get_satisfaction_mall(satisfier),
707            Descriptor::Pkh(ref pkh) => pkh.get_satisfaction_mall(satisfier),
708            Descriptor::Wpkh(ref wpkh) => wpkh.get_satisfaction_mall(satisfier),
709            Descriptor::Wsh(ref wsh) => wsh.get_satisfaction_mall(satisfier),
710            Descriptor::Sh(ref sh) => sh.get_satisfaction_mall(satisfier),
711            Descriptor::LegacyCSFSCov(ref cov) => cov.get_satisfaction_mall(satisfier),
712            Descriptor::Tr(ref tr) => tr.get_satisfaction_mall(satisfier),
713            Descriptor::TrExt(ref tr) => tr.get_satisfaction_mall(satisfier),
714        }
715    }
716
717    /// Attempts to produce a non-malleable satisfying witness and scriptSig to spend an
718    /// output controlled by the given descriptor; add the data to a given
719    /// `TxIn` output.
720    pub fn satisfy<S>(&self, txin: &mut TxIn, satisfier: S) -> Result<(), Error>
721    where
722        S: Satisfier<Pk>,
723    {
724        let (witness, script_sig) = self.get_satisfaction(satisfier)?;
725        txin.witness.script_witness = witness;
726        txin.script_sig = script_sig;
727        Ok(())
728    }
729}
730
731impl<P, Q, Ext> TranslatePk<P, Q> for Descriptor<P, Ext>
732where
733    P: MiniscriptKey,
734    Q: MiniscriptKey,
735    Ext: Extension,
736{
737    type Output = Descriptor<Q, Ext>;
738
739    /// Converts a descriptor using abstract keys to one using specific keys.
740    fn translate_pk<T, E>(&self, t: &mut T) -> Result<Self::Output, E>
741    where
742        T: Translator<P, Q, E>,
743    {
744        let desc = match *self {
745            Descriptor::Bare(ref bare) => Descriptor::Bare(bare.translate_pk(t)?),
746            Descriptor::Pkh(ref pk) => Descriptor::Pkh(pk.translate_pk(t)?),
747            Descriptor::Wpkh(ref pk) => Descriptor::Wpkh(pk.translate_pk(t)?),
748            Descriptor::Sh(ref sh) => Descriptor::Sh(sh.translate_pk(t)?),
749            Descriptor::Wsh(ref wsh) => Descriptor::Wsh(wsh.translate_pk(t)?),
750            Descriptor::Tr(ref tr) => Descriptor::Tr(tr.translate_pk(t)?),
751            Descriptor::TrExt(ref tr) => Descriptor::TrExt(tr.translate_pk(t)?),
752            Descriptor::LegacyCSFSCov(ref cov) => Descriptor::LegacyCSFSCov(cov.translate_pk(t)?),
753        };
754        Ok(desc)
755    }
756}
757
758impl<PExt, QExt, Pk> TranslateExt<PExt, QExt> for Descriptor<Pk, PExt>
759where
760    PExt: Extension + TranslateExt<PExt, QExt, Output = QExt>,
761    QExt: Extension,
762    Pk: MiniscriptKey,
763{
764    type Output = Descriptor<Pk, QExt>;
765
766    /// Converts a descriptor using abstract keys to one using specific keys.
767    #[rustfmt::skip]
768    fn translate_ext<T, E>(&self, t: &mut T) -> Result<Self::Output, E>
769    where
770        T: ExtTranslator<PExt, QExt, E>,
771    {
772        let desc = match *self {
773            Descriptor::Bare(ref bare) => Descriptor::Bare(bare.clone()),
774            Descriptor::Pkh(ref pk) => Descriptor::Pkh(pk.clone()),
775            Descriptor::Wpkh(ref pk) => Descriptor::Wpkh(pk.clone()),
776            Descriptor::Sh(ref sh) => Descriptor::Sh(sh.clone()),
777            Descriptor::Wsh(ref wsh) => Descriptor::Wsh(wsh.clone()),
778            Descriptor::Tr(ref tr) => Descriptor::Tr(tr.clone()),
779            Descriptor::TrExt(ref tr) => Descriptor::TrExt(
780                TranslateExt::<PExt, QExt>::translate_ext(tr, t)?,
781            ),
782            Descriptor::LegacyCSFSCov(ref cov) => {
783                Descriptor::LegacyCSFSCov(TranslateExt::<PExt, QExt>::translate_ext(
784                    cov, t,
785                )?)
786            }
787        };
788        Ok(desc)
789    }
790}
791
792impl<Pk: MiniscriptKey, T: Extension> ForEachKey<Pk> for Descriptor<Pk, T> {
793    fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
794    where
795        Pk: 'a,
796    {
797        match *self {
798            Descriptor::Bare(ref bare) => bare.for_each_key(pred),
799            Descriptor::Pkh(ref pkh) => pkh.for_each_key(pred),
800            Descriptor::Wpkh(ref wpkh) => wpkh.for_each_key(pred),
801            Descriptor::Wsh(ref wsh) => wsh.for_each_key(pred),
802            Descriptor::Sh(ref sh) => sh.for_each_key(pred),
803            Descriptor::LegacyCSFSCov(ref cov) => cov.for_any_key(pred),
804            Descriptor::Tr(ref tr) => tr.for_each_key(pred),
805            Descriptor::TrExt(ref tr) => tr.for_each_key(pred),
806        }
807    }
808}
809
810impl<Ext: Extension + ParseableExt> Descriptor<DescriptorPublicKey, Ext> {
811    /// Whether or not the descriptor has any wildcards
812    #[deprecated(note = "use has_wildcards instead")]
813    pub fn is_deriveable(&self) -> bool {
814        self.has_wildcard()
815    }
816
817    /// Whether or not the descriptor has any wildcards i.e. `/*`.
818    pub fn has_wildcard(&self) -> bool {
819        self.for_any_key(|key| key.has_wildcard())
820    }
821
822    /// Replaces all wildcards (i.e. `/*`) in the descriptor with a particular derivation index,
823    /// turning it into a *definite* descriptor.
824    ///
825    /// # Errors
826    /// - If index ≥ 2^31
827    pub fn at_derivation_index(
828        &self,
829        index: u32,
830    ) -> Result<Descriptor<DefiniteDescriptorKey, Ext>, ConversionError> {
831        struct Derivator(u32);
832
833        impl Translator<DescriptorPublicKey, DefiniteDescriptorKey, ConversionError> for Derivator {
834            fn pk(
835                &mut self,
836                pk: &DescriptorPublicKey,
837            ) -> Result<DefiniteDescriptorKey, ConversionError> {
838                pk.clone().at_derivation_index(self.0)
839            }
840
841            translate_hash_clone!(DescriptorPublicKey, DescriptorPublicKey, ConversionError);
842        }
843        self.translate_pk(&mut Derivator(index))
844    }
845
846    #[deprecated(note = "use at_derivation_index instead")]
847    /// Deprecated name for [`Self::at_derivation_index`].
848    pub fn derive(
849        &self,
850        index: u32,
851    ) -> Result<Descriptor<DefiniteDescriptorKey, Ext>, ConversionError> {
852        self.at_derivation_index(index)
853    }
854
855    /// Convert all the public keys in the descriptor to [`bitcoin::PublicKey`] by deriving them or
856    /// otherwise converting them. All [`bitcoin::key::XOnlyPublicKey`]s are converted to by adding a
857    /// default(0x02) y-coordinate.
858    ///
859    /// This is a shorthand for:
860    ///
861    /// ```
862    /// # use elements_miniscript::{Descriptor, DescriptorPublicKey, bitcoin::secp256k1::Secp256k1};
863    /// # use core::str::FromStr;
864    /// # let descriptor = Descriptor::<DescriptorPublicKey>::from_str("eltr(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)")
865    ///     .expect("Valid ranged descriptor");
866    /// # let index = 42;
867    /// # let secp = Secp256k1::verification_only();
868    /// let derived_descriptor = descriptor.at_derivation_index(index).unwrap().derived_descriptor(&secp).unwrap();
869    /// # assert_eq!(descriptor.derived_descriptor(&secp, index).unwrap(), derived_descriptor);
870    /// ```
871    ///
872    /// and is only here really here for backwards compatbility.
873    /// See [`at_derivation_index`] and `[derived_descriptor`] for more documentation.
874    ///
875    /// [`at_derivation_index`]: Self::at_derivation_index
876    /// [`derived_descriptor`]: crate::DerivedDescriptor::derived_descriptor
877    ///
878    /// # Errors
879    ///
880    /// This function will return an error if hardened derivation is attempted.
881    pub fn derived_descriptor<C: secp256k1_zkp::Verification>(
882        &self,
883        secp: &secp256k1_zkp::Secp256k1<C>,
884        index: u32,
885    ) -> Result<Descriptor<bitcoin::PublicKey, Ext>, ConversionError> {
886        self.at_derivation_index(index)?.derived_descriptor(secp)
887    }
888
889    /// Parse a descriptor that may contain secret keys
890    ///
891    /// Internally turns every secret key found into the corresponding public key and then returns a
892    /// a descriptor that only contains public keys and a map to lookup the secret key given a public key.
893    pub fn parse_descriptor<C: secp256k1_zkp::Signing>(
894        secp: &secp256k1_zkp::Secp256k1<C>,
895        s: &str,
896    ) -> Result<(Descriptor<DescriptorPublicKey, Ext>, KeyMap), Error> {
897        fn parse_key<C: secp256k1::Signing>(
898            s: &str,
899            key_map: &mut KeyMap,
900            secp: &secp256k1::Secp256k1<C>,
901        ) -> Result<DescriptorPublicKey, Error> {
902            let (public_key, secret_key) = match DescriptorSecretKey::from_str(s) {
903                Ok(sk) => (
904                    sk.to_public(secp)
905                        .map_err(|e| Error::Unexpected(e.to_string()))?,
906                    Some(sk),
907                ),
908                Err(_) => (
909                    DescriptorPublicKey::from_str(s)
910                        .map_err(|e| Error::Unexpected(e.to_string()))?,
911                    None,
912                ),
913            };
914
915            if let Some(secret_key) = secret_key {
916                key_map.insert(public_key.clone(), secret_key);
917            }
918
919            Ok(public_key)
920        }
921
922        let mut keymap_pk = KeyMapWrapper(HashMap::new(), secp);
923
924        struct KeyMapWrapper<'a, C: secp256k1::Signing>(KeyMap, &'a secp256k1::Secp256k1<C>);
925
926        impl<'a, C: secp256k1::Signing> Translator<String, DescriptorPublicKey, Error>
927            for KeyMapWrapper<'a, C>
928        {
929            fn pk(&mut self, pk: &String) -> Result<DescriptorPublicKey, Error> {
930                parse_key(pk, &mut self.0, self.1)
931            }
932
933            fn sha256(&mut self, sha256: &String) -> Result<sha256::Hash, Error> {
934                let hash =
935                    sha256::Hash::from_str(sha256).map_err(|e| Error::Unexpected(e.to_string()))?;
936                Ok(hash)
937            }
938
939            fn hash256(&mut self, hash256: &String) -> Result<hash256::Hash, Error> {
940                let hash = hash256::Hash::from_str(hash256)
941                    .map_err(|e| Error::Unexpected(e.to_string()))?;
942                Ok(hash)
943            }
944
945            fn ripemd160(&mut self, ripemd160: &String) -> Result<ripemd160::Hash, Error> {
946                let hash = ripemd160::Hash::from_str(ripemd160)
947                    .map_err(|e| Error::Unexpected(e.to_string()))?;
948                Ok(hash)
949            }
950
951            fn hash160(&mut self, hash160: &String) -> Result<hash160::Hash, Error> {
952                let hash = hash160::Hash::from_str(hash160)
953                    .map_err(|e| Error::Unexpected(e.to_string()))?;
954                Ok(hash)
955            }
956        }
957
958        let descriptor = Descriptor::<String, Ext>::from_str(s)?;
959        let descriptor = descriptor
960            .translate_pk(&mut keymap_pk)
961            .map_err(|e| Error::Unexpected(e.to_string()))?;
962
963        Ok((descriptor, keymap_pk.0))
964    }
965
966    /// Serialize a descriptor to string with its secret keys
967    pub fn to_string_with_secret(&self, key_map: &KeyMap) -> String {
968        struct KeyMapLookUp<'a>(&'a KeyMap);
969
970        impl<'a> Translator<DescriptorPublicKey, String, ()> for KeyMapLookUp<'a> {
971            fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<String, ()> {
972                key_to_string(pk, self.0)
973            }
974
975            fn sha256(&mut self, sha256: &sha256::Hash) -> Result<String, ()> {
976                Ok(sha256.to_string())
977            }
978
979            fn hash256(&mut self, hash256: &hash256::Hash) -> Result<String, ()> {
980                Ok(hash256.to_string())
981            }
982
983            fn ripemd160(&mut self, ripemd160: &ripemd160::Hash) -> Result<String, ()> {
984                Ok(ripemd160.to_string())
985            }
986
987            fn hash160(&mut self, hash160: &hash160::Hash) -> Result<String, ()> {
988                Ok(hash160.to_string())
989            }
990        }
991
992        fn key_to_string(pk: &DescriptorPublicKey, key_map: &KeyMap) -> Result<String, ()> {
993            Ok(match key_map.get(pk) {
994                Some(secret) => secret.to_string(),
995                None => pk.to_string(),
996            })
997        }
998
999        let descriptor = self
1000            .translate_pk(&mut KeyMapLookUp(key_map))
1001            .expect("Translation to string cannot fail");
1002
1003        descriptor.to_string()
1004    }
1005
1006    /// Whether this descriptor contains a key that has multiple derivation paths.
1007    pub fn is_multipath(&self) -> bool {
1008        self.for_any_key(DescriptorPublicKey::is_multipath)
1009    }
1010
1011    /// Get as many descriptors as different paths in this descriptor.
1012    ///
1013    /// For multipath descriptors it will return as many descriptors as there is
1014    /// "parallel" paths. For regular descriptors it will just return itself.
1015    pub fn into_single_descriptors(self) -> Result<Vec<Self>, Error> {
1016        // All single-path descriptors contained in this descriptor.
1017        let mut descriptors = Vec::new();
1018        // We (ab)use `for_any_key` to gather the number of separate descriptors.
1019        if !self.for_any_key(|key| {
1020            // All multipath keys must have the same number of indexes at the "multi-index"
1021            // step. So we can return early if we already populated the vector.
1022            if !descriptors.is_empty() {
1023                return true;
1024            }
1025
1026            match key {
1027                DescriptorPublicKey::Single(..) | DescriptorPublicKey::XPub(..) => false,
1028                DescriptorPublicKey::MultiXPub(xpub) => {
1029                    for _ in 0..xpub.derivation_paths.paths().len() {
1030                        descriptors.push(self.clone());
1031                    }
1032                    true
1033                }
1034            }
1035        }) {
1036            // If there is no multipath key, return early.
1037            return Ok(vec![self]);
1038        }
1039        assert!(!descriptors.is_empty());
1040
1041        // Now, transform the multipath key of each descriptor into a single-key using each index.
1042        struct IndexChoser(usize);
1043        impl Translator<DescriptorPublicKey, DescriptorPublicKey, Error> for IndexChoser {
1044            fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<DescriptorPublicKey, Error> {
1045                match pk {
1046                    DescriptorPublicKey::Single(..) | DescriptorPublicKey::XPub(..) => {
1047                        Ok(pk.clone())
1048                    }
1049                    DescriptorPublicKey::MultiXPub(_) => pk
1050                        .clone()
1051                        .into_single_keys()
1052                        .get(self.0)
1053                        .cloned()
1054                        .ok_or(Error::MultipathDescLenMismatch),
1055                }
1056            }
1057            translate_hash_clone!(DescriptorPublicKey, DescriptorPublicKey, Error);
1058        }
1059
1060        for (i, desc) in descriptors.iter_mut().enumerate() {
1061            let mut index_choser = IndexChoser(i);
1062            *desc = desc.translate_pk(&mut index_choser)?;
1063        }
1064
1065        Ok(descriptors)
1066    }
1067}
1068
1069impl<Ext: Extension + ParseableExt> Descriptor<DescriptorPublicKey, Ext> {
1070    /// Utility method for deriving the descriptor at each index in a range to find one matching
1071    /// `script_pubkey`.
1072    ///
1073    /// If it finds a match then it returns the index it was derived at and the concrete
1074    /// descriptor at that index. If the descriptor is non-derivable then it will simply check the
1075    /// script pubkey against the descriptor and return it if it matches (in this case the index
1076    /// returned will be meaningless).
1077    pub fn find_derivation_index_for_spk<C: secp256k1_zkp::Verification>(
1078        &self,
1079        secp: &secp256k1_zkp::Secp256k1<C>,
1080        script_pubkey: &Script,
1081        range: Range<u32>,
1082    ) -> Result<Option<(u32, Descriptor<bitcoin::PublicKey, Ext>)>, ConversionError> {
1083        let range = if self.has_wildcard() { range } else { 0..1 };
1084
1085        for i in range {
1086            let concrete = self.derived_descriptor(secp, i)?;
1087            if &concrete.script_pubkey() == script_pubkey {
1088                return Ok(Some((i, concrete)));
1089            }
1090        }
1091
1092        Ok(None)
1093    }
1094}
1095
1096impl<Pk: MiniscriptKey, Ext: Extension> Descriptor<Pk, Ext> {
1097    /// Whether this descriptor is a multipath descriptor that contains any 2 multipath keys
1098    /// with a different number of derivation paths.
1099    /// Such a descriptor is invalid according to BIP389.
1100    pub fn multipath_length_mismatch(&self) -> bool {
1101        // (Ab)use `for_each_key` to record the number of derivation paths a multipath key has.
1102        #[derive(PartialEq)]
1103        enum MultipathLenChecker {
1104            SinglePath,
1105            MultipathLen(usize),
1106            LenMismatch,
1107        }
1108
1109        let mut checker = MultipathLenChecker::SinglePath;
1110        self.for_each_key(|key| {
1111            match key.num_der_paths() {
1112                0 | 1 => {}
1113                n => match checker {
1114                    MultipathLenChecker::SinglePath => {
1115                        checker = MultipathLenChecker::MultipathLen(n);
1116                    }
1117                    MultipathLenChecker::MultipathLen(len) => {
1118                        if len != n {
1119                            checker = MultipathLenChecker::LenMismatch;
1120                        }
1121                    }
1122                    MultipathLenChecker::LenMismatch => {}
1123                },
1124            }
1125            true
1126        });
1127
1128        checker == MultipathLenChecker::LenMismatch
1129    }
1130}
1131
1132impl<Ext: Extension> Descriptor<DefiniteDescriptorKey, Ext> {
1133    /// Convert all the public keys in the descriptor to [`bitcoin::PublicKey`] by deriving them or
1134    /// otherwise converting them. All [`bitcoin::key::XOnlyPublicKey`]s are converted to by adding a
1135    /// default(0x02) y-coordinate.
1136    ///
1137    /// # Examples
1138    ///
1139    /// ```
1140    /// # extern crate elements_miniscript as miniscript;
1141    /// use miniscript::descriptor::{Descriptor, DescriptorPublicKey};
1142    /// use miniscript::bitcoin::secp256k1;
1143    /// use std::str::FromStr;
1144    ///
1145    /// // test from bip 86
1146    /// let secp = secp256k1::Secp256k1::verification_only();
1147    /// let descriptor = Descriptor::<DescriptorPublicKey>::from_str("eltr(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)")
1148    ///     .expect("Valid ranged descriptor");
1149    /// let result = descriptor.at_derivation_index(0).unwrap().derived_descriptor(&secp).expect("Non-hardened derivation");
1150    /// assert_eq!(result.to_string(), "eltr(03cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115)#hr5pt2wj");
1151    /// ```
1152    ///
1153    /// # Errors
1154    ///
1155    /// This function will return an error if hardened derivation is attempted.
1156    pub fn derived_descriptor<C: secp256k1::Verification>(
1157        &self,
1158        secp: &secp256k1::Secp256k1<C>,
1159    ) -> Result<Descriptor<bitcoin::PublicKey, Ext>, ConversionError> {
1160        struct Derivator<'a, C: secp256k1::Verification>(&'a secp256k1::Secp256k1<C>);
1161
1162        impl<'a, C: secp256k1::Verification>
1163            Translator<DefiniteDescriptorKey, bitcoin::PublicKey, ConversionError>
1164            for Derivator<'a, C>
1165        {
1166            fn pk(
1167                &mut self,
1168                pk: &DefiniteDescriptorKey,
1169            ) -> Result<bitcoin::PublicKey, ConversionError> {
1170                pk.derive_public_key(self.0)
1171            }
1172
1173            translate_hash_clone!(DefiniteDescriptorKey, bitcoin::PublicKey, ConversionError);
1174        }
1175
1176        let derived = self.translate_pk(&mut Derivator(secp))?;
1177        Ok(derived)
1178    }
1179}
1180
1181impl_from_tree!(
1182    ;T; Extension,
1183    Descriptor<Pk, T>,
1184    /// Parse an expression tree into a descriptor.
1185    fn from_tree(top: &expression::Tree) -> Result<Descriptor<Pk, T>, Error> {
1186        Ok(match (top.name, top.args.len() as u32) {
1187            ("elpkh", 1) => Descriptor::Pkh(Pkh::from_tree(top)?),
1188            ("elwpkh", 1) => Descriptor::Wpkh(Wpkh::from_tree(top)?),
1189            ("elsh", 1) => Descriptor::Sh(Sh::from_tree(top)?),
1190            ("elcovwsh", 2) => Descriptor::LegacyCSFSCov(LegacyCSFSCov::from_tree(top)?),
1191            ("elwsh", 1) => Descriptor::Wsh(Wsh::from_tree(top)?),
1192            ("eltr", _) => Descriptor::Tr(Tr::from_tree(top)?),
1193            _ => Descriptor::Bare(Bare::from_tree(top)?),
1194        })
1195    }
1196);
1197
1198impl_from_str!(
1199    ;T; Extension,
1200    Descriptor<Pk, T>,
1201    type Err = Error;,
1202    fn from_str(s: &str) -> Result<Descriptor<Pk, T>, Error> {
1203        if !s.starts_with(ELMTS_STR) {
1204            return Err(Error::BadDescriptor(String::from(
1205                "Not an Elements Descriptor",
1206            )));
1207        }
1208        // tr tree parsing has special code
1209        // Tr::from_str will check the checksum
1210        // match "tr(" to handle more extensibly
1211        let desc = if s.starts_with(&format!("{}tr", ELMTS_STR)) {
1212            // First try parsing without extensions
1213            match Tr::<Pk, NoExt>::from_str(s) {
1214                Ok(tr) => Descriptor::Tr(tr),
1215                Err(_) => {
1216                    // Try parsing with extensions
1217                    let tr = Tr::<Pk, T>::from_str(s)?;
1218                    Descriptor::TrExt(tr)
1219                }
1220            }
1221        } else {
1222            let desc_str = verify_checksum(s)?;
1223            let top = expression::Tree::from_str(desc_str)?;
1224            expression::FromTree::from_tree(&top)?
1225        };
1226
1227        if desc.multipath_length_mismatch() {
1228            return Err(Error::MultipathDescLenMismatch);
1229        }
1230
1231        Ok(desc)
1232    }
1233);
1234
1235impl<Pk: MiniscriptKey, T: Extension> fmt::Debug for Descriptor<Pk, T> {
1236    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1237        match *self {
1238            Descriptor::Bare(ref sub) => fmt::Debug::fmt(sub, f),
1239            Descriptor::Pkh(ref pkh) => fmt::Debug::fmt(pkh, f),
1240            Descriptor::Wpkh(ref wpkh) => fmt::Debug::fmt(wpkh, f),
1241            Descriptor::Sh(ref sub) => fmt::Debug::fmt(sub, f),
1242            Descriptor::Wsh(ref sub) => fmt::Debug::fmt(sub, f),
1243            Descriptor::Tr(ref tr) => fmt::Debug::fmt(tr, f),
1244            Descriptor::TrExt(ref tr) => fmt::Debug::fmt(tr, f),
1245            Descriptor::LegacyCSFSCov(ref cov) => fmt::Debug::fmt(cov, f),
1246        }
1247    }
1248}
1249
1250impl<Pk: MiniscriptKey, T: Extension> fmt::Display for Descriptor<Pk, T> {
1251    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1252        match *self {
1253            Descriptor::Bare(ref sub) => fmt::Display::fmt(sub, f),
1254            Descriptor::Pkh(ref pkh) => fmt::Display::fmt(pkh, f),
1255            Descriptor::Wpkh(ref wpkh) => fmt::Display::fmt(wpkh, f),
1256            Descriptor::Sh(ref sub) => fmt::Display::fmt(sub, f),
1257            Descriptor::Wsh(ref sub) => fmt::Display::fmt(sub, f),
1258            Descriptor::Tr(ref tr) => fmt::Display::fmt(tr, f),
1259            Descriptor::TrExt(ref tr) => fmt::Display::fmt(tr, f),
1260            Descriptor::LegacyCSFSCov(ref cov) => fmt::Display::fmt(cov, f),
1261        }
1262    }
1263}
1264
1265serde_string_impl_pk!(Descriptor, "a script descriptor", T; Extension);
1266
1267#[cfg(test)]
1268mod tests {
1269    use std::collections::HashMap;
1270    use std::str::FromStr;
1271
1272    use bitcoin;
1273    use bitcoin::{bip32, PublicKey};
1274    use elements::hashes::{hash160, sha256};
1275    use elements::hex::{FromHex, ToHex};
1276    use elements::opcodes::all::{OP_CLTV, OP_CSV};
1277    use elements::script::Instruction;
1278    use elements::{opcodes, script, Sequence};
1279
1280    use super::checksum::desc_checksum;
1281    use super::tr::Tr;
1282    use super::*;
1283    use crate::descriptor::key::Wildcard;
1284    use crate::descriptor::{DescriptorPublicKey, DescriptorXKey};
1285    use crate::miniscript::satisfy::ElementsSig;
1286    #[cfg(feature = "compiler")]
1287    use crate::policy;
1288    use crate::{hex_script, Descriptor, Error, Miniscript, NoExt, Satisfier};
1289
1290    type StdDescriptor = Descriptor<PublicKey, CovenantExt<CovExtArgs>>;
1291    const TEST_PK: &str =
1292        "elpk(020000000000000000000000000000000000000000000000000000000000000002)";
1293
1294    fn roundtrip_descriptor(s: &str) {
1295        let desc = Descriptor::<String>::from_str(s).unwrap();
1296        let output = desc.to_string();
1297        let normalize_aliases = s.replace("c:pk_k(", "pk(").replace("c:pk_h(", "pkh(");
1298        assert_eq!(
1299            format!(
1300                "{}#{}",
1301                &normalize_aliases,
1302                desc_checksum(&normalize_aliases).unwrap()
1303            ),
1304            output
1305        );
1306    }
1307
1308    // helper function to create elements txin from scriptsig and witness
1309    fn elements_txin(script_sig: Script, witness: Vec<Vec<u8>>) -> elements::TxIn {
1310        let txin_witness = elements::TxInWitness {
1311            script_witness: witness,
1312            ..Default::default()
1313        };
1314        elements::TxIn {
1315            previous_output: elements::OutPoint::default(),
1316            script_sig,
1317            sequence: Sequence::from_height(100),
1318            is_pegin: false,
1319            asset_issuance: elements::AssetIssuance::default(),
1320            witness: txin_witness,
1321        }
1322    }
1323
1324    #[test]
1325    fn desc_rtt_tests() {
1326        roundtrip_descriptor("elc:pk_k()");
1327        roundtrip_descriptor("elwsh(pk())");
1328        roundtrip_descriptor("elwsh(c:pk_k())");
1329        roundtrip_descriptor("elc:pk_h()");
1330    }
1331    #[test]
1332    fn parse_descriptor() {
1333        StdDescriptor::from_str("(").unwrap_err();
1334        StdDescriptor::from_str("(x()").unwrap_err();
1335        StdDescriptor::from_str("(\u{7f}()3").unwrap_err();
1336        StdDescriptor::from_str("pk()").unwrap_err();
1337        StdDescriptor::from_str("nl:0").unwrap_err(); //issue 63
1338        let compressed_pk = "02be5645686309c6e6736dbd93940707cc9143d3cf29f1b877ff340e2cb2d259cf";
1339        assert_eq!(
1340            StdDescriptor::from_str("elsh(sortedmulti)")
1341                .unwrap_err()
1342                .to_string(),
1343            "unexpected «no arguments given for sortedmulti»"
1344        ); //issue 202
1345        assert_eq!(
1346            StdDescriptor::from_str(&format!("elsh(sortedmulti(2,{}))", compressed_pk))
1347                .unwrap_err()
1348                .to_string(),
1349            "unexpected «higher threshold than there were keys in sortedmulti»"
1350        ); //issue 202
1351
1352        StdDescriptor::from_str(TEST_PK).unwrap();
1353        // fuzzer
1354        StdDescriptor::from_str("slip77").unwrap_err();
1355
1356        let uncompressed_pk =
1357        "0414fc03b8df87cd7b872996810db8458d61da8448e531569c8517b469a119d267be5645686309c6e6736dbd93940707cc9143d3cf29f1b877ff340e2cb2d259cf";
1358
1359        // Context tests
1360        StdDescriptor::from_str(&format!("elpk({})", uncompressed_pk)).unwrap();
1361        StdDescriptor::from_str(&format!("elpkh({})", uncompressed_pk)).unwrap();
1362        StdDescriptor::from_str(&format!("elsh(pk({}))", uncompressed_pk)).unwrap();
1363        StdDescriptor::from_str(&format!("elwpkh({})", uncompressed_pk)).unwrap_err();
1364        StdDescriptor::from_str(&format!("elsh(wpkh({}))", uncompressed_pk)).unwrap_err();
1365        StdDescriptor::from_str(&format!("elwsh(pk{})", uncompressed_pk)).unwrap_err();
1366        StdDescriptor::from_str(&format!("elsh(wsh(pk{}))", uncompressed_pk)).unwrap_err();
1367        StdDescriptor::from_str(&format!(
1368            "elor_i(pk({}),pk({}))",
1369            uncompressed_pk, uncompressed_pk
1370        ))
1371        .unwrap_err();
1372    }
1373
1374    #[test]
1375    pub fn script_pubkey() {
1376        let bare = StdDescriptor::from_str(
1377            "elmulti(1,020000000000000000000000000000000000000000000000000000000000000002)",
1378        )
1379        .unwrap();
1380        assert_eq!(
1381            bare.script_pubkey(),
1382            hex_script(
1383                "512102000000000000000000000000000000000000000000000000000000000000000251ae"
1384            )
1385        );
1386        assert_eq!(
1387            bare.address(&elements::AddressParams::ELEMENTS)
1388                .unwrap_err()
1389                .to_string(),
1390            "Bare descriptors don't have address"
1391        );
1392
1393        let pk = StdDescriptor::from_str(TEST_PK).unwrap();
1394        assert_eq!(
1395            pk.script_pubkey(),
1396            elements::Script::from(vec![
1397                0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1398                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1399                0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xac,
1400            ])
1401        );
1402
1403        let pkh = StdDescriptor::from_str(
1404            "elpkh(\
1405             020000000000000000000000000000000000000000000000000000000000000002\
1406             )",
1407        )
1408        .unwrap();
1409        assert_eq!(
1410            pkh.script_pubkey(),
1411            script::Builder::new()
1412                .push_opcode(opcodes::all::OP_DUP)
1413                .push_opcode(opcodes::all::OP_HASH160)
1414                .push_slice(
1415                    &hash160::Hash::from_str("84e9ed95a38613f0527ff685a9928abe2d4754d4",).unwrap()
1416                        [..]
1417                )
1418                .push_opcode(opcodes::all::OP_EQUALVERIFY)
1419                .push_opcode(opcodes::all::OP_CHECKSIG)
1420                .into_script()
1421        );
1422        assert_eq!(
1423            pkh.address(&elements::AddressParams::ELEMENTS,)
1424                .unwrap()
1425                .to_string(),
1426            "2dmYXpSu8YP6aLcJYhHfB1C19mdzSx2GPB9"
1427        );
1428
1429        let wpkh = StdDescriptor::from_str(
1430            "elwpkh(\
1431             020000000000000000000000000000000000000000000000000000000000000002\
1432             )",
1433        )
1434        .unwrap();
1435        assert_eq!(
1436            wpkh.script_pubkey(),
1437            script::Builder::new()
1438                .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1439                .push_slice(
1440                    &hash160::Hash::from_str("84e9ed95a38613f0527ff685a9928abe2d4754d4",).unwrap()
1441                        [..]
1442                )
1443                .into_script()
1444        );
1445        assert_eq!(
1446            wpkh.address(&elements::AddressParams::ELEMENTS,)
1447                .unwrap()
1448                .to_string(),
1449            "ert1qsn57m9drscflq5nl76z6ny52hck5w4x57m69k3"
1450        );
1451
1452        let shwpkh = StdDescriptor::from_str(
1453            "elsh(wpkh(\
1454             020000000000000000000000000000000000000000000000000000000000000002\
1455             ))",
1456        )
1457        .unwrap();
1458        assert_eq!(
1459            shwpkh.script_pubkey(),
1460            script::Builder::new()
1461                .push_opcode(opcodes::all::OP_HASH160)
1462                .push_slice(
1463                    &hash160::Hash::from_str("f1c3b9a431134cb90a500ec06e0067cfa9b8bba7",).unwrap()
1464                        [..]
1465                )
1466                .push_opcode(opcodes::all::OP_EQUAL)
1467                .into_script()
1468        );
1469        assert_eq!(
1470            shwpkh
1471                .address(&elements::AddressParams::ELEMENTS,)
1472                .unwrap()
1473                .to_string(),
1474            "XZPaAbg6M83Fq5NqvbEGZ5kwy9RKSTke2s"
1475        );
1476
1477        let sh = StdDescriptor::from_str(
1478            "elsh(c:pk_k(\
1479             020000000000000000000000000000000000000000000000000000000000000002\
1480             ))",
1481        )
1482        .unwrap();
1483        assert_eq!(
1484            sh.script_pubkey(),
1485            script::Builder::new()
1486                .push_opcode(opcodes::all::OP_HASH160)
1487                .push_slice(
1488                    &hash160::Hash::from_str("aa5282151694d3f2f32ace7d00ad38f927a33ac8",).unwrap()
1489                        [..]
1490                )
1491                .push_opcode(opcodes::all::OP_EQUAL)
1492                .into_script()
1493        );
1494        assert_eq!(
1495            sh.address(&elements::AddressParams::ELEMENTS,)
1496                .unwrap()
1497                .to_string(),
1498            "XSspZXDJu2XVh8AKC7qF3L7x79Qy67JhQb"
1499        );
1500
1501        let wsh = StdDescriptor::from_str(
1502            "elwsh(c:pk_k(\
1503             020000000000000000000000000000000000000000000000000000000000000002\
1504             ))",
1505        )
1506        .unwrap();
1507        assert_eq!(
1508            wsh.script_pubkey(),
1509            script::Builder::new()
1510                .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1511                .push_slice(
1512                    &sha256::Hash::from_str(
1513                        "\
1514                         f9379edc8983152dc781747830075bd5\
1515                         3896e4b0ce5bff73777fd77d124ba085\
1516                         "
1517                    )
1518                    .unwrap()[..]
1519                )
1520                .into_script()
1521        );
1522        assert_eq!(
1523            wsh.address(&elements::AddressParams::ELEMENTS,)
1524                .unwrap()
1525                .to_string(),
1526            "ert1qlymeahyfsv2jm3upw3urqp6m65ufde9seedl7umh0lth6yjt5zzsan9u2t"
1527        );
1528
1529        let shwsh = StdDescriptor::from_str(
1530            "elsh(wsh(c:pk_k(\
1531             020000000000000000000000000000000000000000000000000000000000000002\
1532             )))",
1533        )
1534        .unwrap();
1535        assert_eq!(
1536            shwsh.script_pubkey(),
1537            script::Builder::new()
1538                .push_opcode(opcodes::all::OP_HASH160)
1539                .push_slice(
1540                    &hash160::Hash::from_str("4bec5d7feeed99e1d0a23fe32a4afe126a7ff07e",).unwrap()
1541                        [..]
1542                )
1543                .push_opcode(opcodes::all::OP_EQUAL)
1544                .into_script()
1545        );
1546        assert_eq!(
1547            shwsh
1548                .address(&elements::AddressParams::ELEMENTS,)
1549                .unwrap()
1550                .to_string(),
1551            "XJGggUb965TvGF2VCxp9EQGmZTxMeDjwQQ"
1552        );
1553    }
1554
1555    #[test]
1556    fn satisfy() {
1557        let secp = secp256k1_zkp::Secp256k1::new();
1558        let sk =
1559            secp256k1_zkp::SecretKey::from_slice(&b"sally was a secret key, she said"[..]).unwrap();
1560        let pk = bitcoin::PublicKey {
1561            inner: secp256k1_zkp::PublicKey::from_secret_key(&secp, &sk),
1562            compressed: true,
1563        };
1564        let msg =
1565            secp256k1_zkp::Message::from_digest_slice(&b"michael was a message, amusingly"[..])
1566                .expect("32 bytes");
1567        let sig = secp.sign_ecdsa(&msg, &sk);
1568        let mut sigser = sig.serialize_der().to_vec();
1569        sigser.push(0x01); // sighash_all
1570
1571        struct SimpleSat {
1572            sig: secp256k1_zkp::ecdsa::Signature,
1573            pk: bitcoin::PublicKey,
1574        }
1575
1576        impl Satisfier<bitcoin::PublicKey> for SimpleSat {
1577            fn lookup_ecdsa_sig(&self, pk: &bitcoin::PublicKey) -> Option<ElementsSig> {
1578                if *pk == self.pk {
1579                    Some((self.sig, elements::EcdsaSighashType::All))
1580                } else {
1581                    None
1582                }
1583            }
1584        }
1585
1586        let satisfier = SimpleSat { sig, pk };
1587        let ms = ms_str!("c:pk_k({})", pk);
1588
1589        let mut txin = elements::TxIn {
1590            previous_output: elements::OutPoint::default(),
1591            script_sig: Script::new(),
1592            sequence: Sequence::from_height(100),
1593            is_pegin: false,
1594            asset_issuance: elements::AssetIssuance::default(),
1595            witness: elements::TxInWitness::default(),
1596        };
1597        let bare: Descriptor<_, NoExt> = Descriptor::new_bare(ms).unwrap();
1598
1599        bare.satisfy(&mut txin, &satisfier).expect("satisfaction");
1600        assert_eq!(
1601            txin,
1602            elements_txin(
1603                script::Builder::new().push_slice(&sigser[..]).into_script(),
1604                vec![]
1605            ),
1606        );
1607        assert_eq!(bare.unsigned_script_sig(), elements::Script::new());
1608
1609        let pkh: Descriptor<_, NoExt> = Descriptor::new_pkh(pk);
1610        pkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1611        assert_eq!(
1612            txin,
1613            elements_txin(
1614                script::Builder::new()
1615                    .push_slice(&sigser[..])
1616                    .push_key(&pk)
1617                    .into_script(),
1618                vec![]
1619            )
1620        );
1621        assert_eq!(pkh.unsigned_script_sig(), elements::Script::new());
1622
1623        let wpkh: Descriptor<_, NoExt> = Descriptor::new_wpkh(pk).unwrap();
1624        wpkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1625        assert_eq!(
1626            txin,
1627            elements_txin(Script::new(), vec![sigser.clone(), pk.to_bytes(),])
1628        );
1629        assert_eq!(wpkh.unsigned_script_sig(), elements::Script::new());
1630
1631        let shwpkh: Descriptor<_, NoExt> = Descriptor::new_sh_wpkh(pk).unwrap();
1632        shwpkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1633        let redeem_script = script::Builder::new()
1634            .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1635            .push_slice(
1636                &hash160::Hash::from_str("d1b2a1faf62e73460af885c687dee3b7189cd8ab").unwrap()[..],
1637            )
1638            .into_script();
1639        let expected_ssig = script::Builder::new()
1640            .push_slice(&redeem_script[..])
1641            .into_script();
1642        assert_eq!(
1643            txin,
1644            elements_txin(expected_ssig.clone(), vec![sigser.clone(), pk.to_bytes()])
1645        );
1646        assert_eq!(shwpkh.unsigned_script_sig(), expected_ssig);
1647
1648        let ms = ms_str!("c:pk_k({})", pk);
1649        let sh: Descriptor<_, NoExt> = Descriptor::new_sh(ms.clone()).unwrap();
1650        sh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1651        let expected_ssig = script::Builder::new()
1652            .push_slice(&sigser[..])
1653            .push_slice(&ms.encode()[..])
1654            .into_script();
1655        assert_eq!(txin, elements_txin(expected_ssig, vec![]));
1656        assert_eq!(sh.unsigned_script_sig(), Script::new());
1657
1658        let ms = ms_str!("c:pk_k({})", pk);
1659
1660        let wsh: Descriptor<_, NoExt> = Descriptor::new_wsh(ms.clone()).unwrap();
1661        wsh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1662        assert_eq!(
1663            txin,
1664            elements_txin(
1665                Script::new(),
1666                vec![sigser.clone(), ms.encode().into_bytes()]
1667            )
1668        );
1669        assert_eq!(wsh.unsigned_script_sig(), Script::new());
1670
1671        let shwsh: Descriptor<_, NoExt> = Descriptor::new_sh_wsh(ms.clone()).unwrap();
1672        shwsh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1673        let expected_ssig = script::Builder::new()
1674            .push_slice(&ms.encode().to_v0_p2wsh()[..])
1675            .into_script();
1676        assert_eq!(
1677            txin,
1678            elements_txin(
1679                expected_ssig.clone(),
1680                vec![sigser.clone(), ms.encode().into_bytes(),]
1681            )
1682        );
1683        assert_eq!(shwsh.unsigned_script_sig(), expected_ssig);
1684    }
1685
1686    #[test]
1687    fn after_is_cltv() {
1688        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("elwsh(after(1000))").unwrap();
1689        let script = descriptor.explicit_script().unwrap();
1690
1691        let actual_instructions: Vec<_> = script.instructions().collect();
1692        let check = actual_instructions.last().unwrap();
1693
1694        assert_eq!(check, &Ok(Instruction::Op(OP_CLTV)))
1695    }
1696
1697    #[test]
1698    fn older_is_csv() {
1699        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("elwsh(older(1000))").unwrap();
1700        let script = descriptor.explicit_script().unwrap();
1701
1702        let actual_instructions: Vec<_> = script.instructions().collect();
1703        let check = actual_instructions.last().unwrap();
1704
1705        assert_eq!(check, &Ok(Instruction::Op(OP_CSV)))
1706    }
1707
1708    #[test]
1709    fn tr_roundtrip_key() {
1710        let script = Tr::<String>::from_str("eltr()").unwrap().to_string();
1711        assert_eq!(script, format!("eltr()#sux3r82e"))
1712    }
1713
1714    #[test]
1715    fn tr_roundtrip_script() {
1716        let descriptor = Tr::<String>::from_str("eltr(,{pk(),pk()})")
1717            .unwrap()
1718            .to_string();
1719
1720        assert_eq!(descriptor, "eltr(,{pk(),pk()})#lxgcxh02");
1721
1722        let descriptor = Descriptor::<String>::from_str("eltr(A,{pk(B),pk(C)})")
1723            .unwrap()
1724            .to_string();
1725        assert_eq!(descriptor, "eltr(A,{pk(B),pk(C)})#cx98s50f");
1726    }
1727
1728    #[test]
1729    fn tr_roundtrip_tree() {
1730        let p1 = "020000000000000000000000000000000000000000000000000000000000000001";
1731        let p2 = "020000000000000000000000000000000000000000000000000000000000000002";
1732        let p3 = "020000000000000000000000000000000000000000000000000000000000000003";
1733        let p4 = "020000000000000000000000000000000000000000000000000000000000000004";
1734        let p5 = "03f8551772d66557da28c1de858124f365a8eb30ce6ad79c10e0f4c546d0ab0f82";
1735        let descriptor = Tr::<PublicKey>::from_str(&format!(
1736            "eltr({},{{pk({}),{{pk({}),or_d(pk({}),pkh({}))}}}})",
1737            p1, p2, p3, p4, p5
1738        ))
1739        .unwrap()
1740        .to_string();
1741
1742        // p5.to_pubkeyhash() = 516ca378e588a7ed71336147e2a72848b20aca1a
1743        assert_eq!(
1744            descriptor,
1745            format!(
1746                "eltr({},{{pk({}),{{pk({}),or_d(pk({}),pkh({}))}}}})#y9kzzx3w",
1747                p1, p2, p3, p4, p5
1748            )
1749        )
1750    }
1751
1752    #[test]
1753    fn tr_script_pubkey() {
1754        let key = Descriptor::<bitcoin::PublicKey>::from_str(
1755            "eltr(02e20e746af365e86647826397ba1c0e0d5cb685752976fe2f326ab76bdc4d6ee9)",
1756        )
1757        .unwrap();
1758        assert_eq!(
1759            key.script_pubkey().to_hex(),
1760            "51203f48e7c6203a75722733e3d9d06638da38d946066159c64684caf1622b2b0e33"
1761        )
1762    }
1763
1764    #[test]
1765    fn roundtrip_tests() {
1766        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("elmulti");
1767        assert_eq!(
1768            descriptor.unwrap_err().to_string(),
1769            "unexpected «no arguments given»"
1770        )
1771    }
1772
1773    #[test]
1774    fn empty_thresh() {
1775        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("elthresh");
1776        assert_eq!(
1777            descriptor.unwrap_err().to_string(),
1778            "unexpected «no arguments given»"
1779        )
1780    }
1781
1782    #[test]
1783    fn witness_stack_for_andv_is_arranged_in_correct_order() {
1784        // arrange
1785        let a = bitcoin::PublicKey::from_str(
1786            "02937402303919b3a2ee5edd5009f4236f069bf75667b8e6ecf8e5464e20116a0e",
1787        )
1788        .unwrap();
1789        let sig_a = secp256k1_zkp::ecdsa::Signature::from_str("3045022100a7acc3719e9559a59d60d7b2837f9842df30e7edcd754e63227e6168cec72c5d022066c2feba4671c3d99ea75d9976b4da6c86968dbf3bab47b1061e7a1966b1778c").unwrap();
1790
1791        let b = bitcoin::PublicKey::from_str(
1792            "02eb64639a17f7334bb5a1a3aad857d6fec65faef439db3de72f85c88bc2906ad3",
1793        )
1794        .unwrap();
1795        let sig_b = secp256k1_zkp::ecdsa::Signature::from_str("3044022075b7b65a7e6cd386132c5883c9db15f9a849a0f32bc680e9986398879a57c276022056d94d12255a4424f51c700ac75122cb354895c9f2f88f0cbb47ba05c9c589ba").unwrap();
1796
1797        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str(&format!(
1798            "elwsh(and_v(v:pk({A}),pk({B})))",
1799            A = a,
1800            B = b
1801        ))
1802        .unwrap();
1803
1804        let mut txin = elements_txin(Script::new(), vec![]);
1805        let satisfier = {
1806            let mut satisfier = HashMap::with_capacity(2);
1807
1808            satisfier.insert(a, (sig_a, ::elements::EcdsaSighashType::All));
1809            satisfier.insert(b, (sig_b, ::elements::EcdsaSighashType::All));
1810
1811            satisfier
1812        };
1813
1814        // act
1815        descriptor.satisfy(&mut txin, &satisfier).unwrap();
1816
1817        // assert
1818        let witness0 = &txin.witness.script_witness[0];
1819        let witness1 = &txin.witness.script_witness[1];
1820
1821        let sig0 =
1822            secp256k1_zkp::ecdsa::Signature::from_der(&witness0[..witness0.len() - 1]).unwrap();
1823        let sig1 =
1824            secp256k1_zkp::ecdsa::Signature::from_der(&witness1[..witness1.len() - 1]).unwrap();
1825
1826        // why are we asserting this way?
1827        // The witness stack is evaluated from top to bottom. Given an `and` instruction, the left arm of the and is going to evaluate first,
1828        // meaning the next witness element (on a three element stack, that is the middle one) needs to be the signature for the left side of the `and`.
1829        // The left side of the `and` performs a CHECKSIG against public key `a` so `sig1` needs to be `sig_a` and `sig0` needs to be `sig_b`.
1830        assert_eq!(sig1, sig_a);
1831        assert_eq!(sig0, sig_b);
1832    }
1833
1834    #[test]
1835    fn test_scriptcode() {
1836        // P2WPKH (from bip143 test vectors)
1837        let descriptor = Descriptor::<PublicKey>::from_str(
1838            "elwpkh(025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357)",
1839        )
1840        .unwrap();
1841        assert_eq!(
1842            *descriptor.script_code().unwrap().as_bytes(),
1843            Vec::<u8>::from_hex("76a9141d0f172a0ecb48aee1be1f2687d2963ae33f71a188ac").unwrap()[..]
1844        );
1845
1846        // P2SH-P2WPKH (from bip143 test vectors)
1847        let descriptor = Descriptor::<PublicKey>::from_str(
1848            "elsh(wpkh(03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873))",
1849        )
1850        .unwrap();
1851        assert_eq!(
1852            *descriptor.script_code().unwrap().as_bytes(),
1853            Vec::<u8>::from_hex("76a91479091972186c449eb1ded22b78e40d009bdf008988ac").unwrap()[..]
1854        );
1855
1856        // P2WSH (from bitcoind's `createmultisig`)
1857        let descriptor = Descriptor::<PublicKey>::from_str(
1858            "elwsh(multi(2,03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd,03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626))",
1859        )
1860        .unwrap();
1861        assert_eq!(
1862            *descriptor
1863                .script_code().unwrap()
1864                .as_bytes(),
1865            Vec::<u8>::from_hex("522103789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd2103dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a6162652ae").unwrap()[..]
1866        );
1867
1868        // P2SH-P2WSH (from bitcoind's `createmultisig`)
1869        let descriptor = Descriptor::<PublicKey>::from_str("elsh(wsh(multi(2,03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd,03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626)))").unwrap();
1870        assert_eq!(
1871            *descriptor
1872                .script_code().unwrap()
1873                .as_bytes(),
1874            Vec::<u8>::from_hex("522103789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd2103dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a6162652ae")
1875                .unwrap()[..]
1876        );
1877    }
1878
1879    #[test]
1880    fn parse_descriptor_key() {
1881        // With a wildcard
1882        let key = "[78412e3a/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*";
1883        let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1884            origin: Some((
1885                bip32::Fingerprint::from([0x78, 0x41, 0x2e, 0x3a]),
1886                (&[
1887                    bip32::ChildNumber::from_hardened_idx(44).unwrap(),
1888                    bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1889                    bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1890                ][..])
1891                .into(),
1892            )),
1893            xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1894            derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1895            wildcard: Wildcard::Unhardened,
1896        });
1897        assert_eq!(expected, key.parse().unwrap());
1898        assert_eq!(format!("{}", expected), key);
1899
1900        // Without origin
1901        let key = "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1";
1902        let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1903            origin: None,
1904            xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1905            derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1906            wildcard: Wildcard::None,
1907        });
1908        assert_eq!(expected, key.parse().unwrap());
1909        assert_eq!(format!("{}", expected), key);
1910
1911        // Testnet tpub
1912        let key = "tpubD6NzVbkrYhZ4YqYr3amYH15zjxHvBkUUeadieW8AxTZC7aY2L8aPSk3tpW6yW1QnWzXAB7zoiaNMfwXPPz9S68ZCV4yWvkVXjdeksLskCed/1";
1913        let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1914            origin: None,
1915            xkey: bip32::Xpub::from_str("tpubD6NzVbkrYhZ4YqYr3amYH15zjxHvBkUUeadieW8AxTZC7aY2L8aPSk3tpW6yW1QnWzXAB7zoiaNMfwXPPz9S68ZCV4yWvkVXjdeksLskCed").unwrap(),
1916            derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1917            wildcard: Wildcard::None,
1918        });
1919        assert_eq!(expected, key.parse().unwrap());
1920        assert_eq!(format!("{}", expected), key);
1921
1922        // Without derivation path
1923        let key = "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL";
1924        let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1925            origin: None,
1926            xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1927            derivation_path: bip32::DerivationPath::from(&[][..]),
1928            wildcard: Wildcard::None,
1929        });
1930        assert_eq!(expected, key.parse().unwrap());
1931        assert_eq!(format!("{}", expected), key);
1932
1933        // Raw (compressed) pubkey
1934        let key = "03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8";
1935        let expected = DescriptorPublicKey::Single(SinglePub {
1936            key: SinglePubKey::FullKey(
1937                bitcoin::PublicKey::from_str(
1938                    "03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8",
1939                )
1940                .unwrap(),
1941            ),
1942            origin: None,
1943        });
1944        assert_eq!(expected, key.parse().unwrap());
1945        assert_eq!(format!("{}", expected), key);
1946
1947        // Raw (uncompressed) pubkey
1948        let key = "04f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446a";
1949        let expected = DescriptorPublicKey::Single(SinglePub {
1950            key: SinglePubKey::FullKey(bitcoin::PublicKey::from_str(
1951                "04f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446a",
1952            )
1953            .unwrap()),
1954            origin: None,
1955        });
1956        assert_eq!(expected, key.parse().unwrap());
1957        assert_eq!(format!("{}", expected), key);
1958
1959        // Raw pubkey with origin
1960        let desc =
1961            "[78412e3a/0'/42/0']0231c7d3fc85c148717848033ce276ae2b464a4e2c367ed33886cc428b8af48ff8";
1962        let expected = DescriptorPublicKey::Single(SinglePub {
1963            key: SinglePubKey::FullKey(
1964                bitcoin::PublicKey::from_str(
1965                    "0231c7d3fc85c148717848033ce276ae2b464a4e2c367ed33886cc428b8af48ff8",
1966                )
1967                .unwrap(),
1968            ),
1969            origin: Some((
1970                bip32::Fingerprint::from([0x78, 0x41, 0x2e, 0x3a]),
1971                (&[
1972                    bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1973                    bip32::ChildNumber::from_normal_idx(42).unwrap(),
1974                    bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1975                ][..])
1976                    .into(),
1977            )),
1978        });
1979        assert_eq!(expected, desc.parse().expect("Parsing desc"));
1980        assert_eq!(format!("{}", expected), desc);
1981    }
1982
1983    #[test]
1984    fn test_sortedmulti() {
1985        fn _test_sortedmulti(raw_desc_one: &str, raw_desc_two: &str, raw_addr_expected: &str) {
1986            let secp_ctx = secp256k1_zkp::Secp256k1::verification_only();
1987            let index = 5;
1988
1989            // Parse descriptor
1990            let desc_one = Descriptor::<DescriptorPublicKey>::from_str(raw_desc_one).unwrap();
1991            let desc_two = Descriptor::<DescriptorPublicKey>::from_str(raw_desc_two).unwrap();
1992
1993            // Same string formatting
1994            assert_eq!(desc_one.to_string(), raw_desc_one);
1995            assert_eq!(desc_two.to_string(), raw_desc_two);
1996
1997            // Same address
1998            let addr_one = desc_one
1999                .at_derivation_index(index)
2000                .unwrap()
2001                .derived_descriptor(&secp_ctx)
2002                .unwrap()
2003                .address(&elements::AddressParams::ELEMENTS)
2004                .unwrap();
2005            let addr_two = desc_two
2006                .at_derivation_index(index)
2007                .unwrap()
2008                .derived_descriptor(&secp_ctx)
2009                .unwrap()
2010                .address(&elements::AddressParams::ELEMENTS)
2011                .unwrap();
2012            let addr_expected = elements::Address::from_str(raw_addr_expected).unwrap();
2013            assert_eq!(addr_one, addr_expected);
2014            assert_eq!(addr_two, addr_expected);
2015        }
2016
2017        // P2SH and pubkeys
2018        _test_sortedmulti(
2019            "elsh(sortedmulti(1,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352))#tse3qz98",
2020            "elsh(sortedmulti(1,0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))#ptnf05qc",
2021            "XUDXJZnP2GXsKRKdxSLKzJM1iZ4gbbyrGh",
2022        );
2023
2024        // P2WSH and single-xpub descriptor
2025        _test_sortedmulti(
2026            "elwsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#a8h2v83d",
2027            "elwsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB))#qfcn7ujk",
2028            "ert1qpq2cfgz5lktxzr5zqv7nrzz46hsvq3492ump9pz8rzcl8wqtwqcs2yqnuv",
2029        );
2030
2031        // P2WSH-P2SH and ranged descriptor
2032        _test_sortedmulti(
2033            "elsh(wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*)))#l7qy253t",
2034            "elsh(wsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*)))#0gpee5cl",
2035            "XBkDY63XnRTz6BbwzJi3ifGhBwLTomEzkq",
2036        );
2037    }
2038
2039    #[test]
2040    fn test_parse_descriptor() {
2041        let secp = &secp256k1_zkp::Secp256k1::signing_only();
2042        let (descriptor, key_map) = Descriptor::<_, NoExt>::parse_descriptor(secp, "elwpkh(tprv8ZgxMBicQKsPcwcD4gSnMti126ZiETsuX7qwrtMypr6FBwAP65puFn4v6c3jrN9VwtMRMph6nyT63NrfUL4C3nBzPcduzVSuHD7zbX2JKVc/44'/0'/0'/0/*)").unwrap();
2043        assert_eq!(descriptor.to_string(), "elwpkh([2cbe2a6d/44'/0'/0']tpubDCvNhURocXGZsLNqWcqD3syHTqPXrMSTwi8feKVwAcpi29oYKsDD3Vex7x2TDneKMVN23RbLprfxB69v94iYqdaYHsVz3kPR37NQXeqouVz/0/*)#pznhhta9");
2044        assert_eq!(key_map.len(), 1);
2045
2046        // https://github.com/bitcoin/bitcoin/blob/7ae86b3c6845873ca96650fc69beb4ae5285c801/src/test/descriptor_tests.cpp#L355-L360
2047        macro_rules! check_invalid_checksum {
2048            ($secp: ident,$($desc: expr),*) => {
2049                $(
2050                    match Descriptor::<_, NoExt>::parse_descriptor($secp, $desc) {
2051                        Err(Error::BadDescriptor(_)) => {},
2052                        Err(e) => panic!("Expected bad checksum for {}, got '{}'", $desc, e),
2053                        _ => panic!("Invalid checksum treated as valid: {}", $desc),
2054                    };
2055                )*
2056            };
2057        }
2058        check_invalid_checksum!(secp,
2059            "elsh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#",
2060            "elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#",
2061            "elsh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxf",
2062            "elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5tq",
2063            "elsh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxf",
2064            "elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5",
2065            "elsh(multi(3,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfy",
2066            "elsh(multi(3,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t",
2067            "elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjq09x4t",
2068            "elsh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))##ggssrxfy",
2069            "elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))##tjq09x4t"
2070        );
2071
2072        Descriptor::<_, NoExt>::parse_descriptor(secp, "elsh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#9s2ngs7u").expect("Valid descriptor with checksum");
2073        Descriptor::<_, NoExt>::parse_descriptor(secp, "elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#uklept69").expect("Valid descriptor with checksum");
2074    }
2075
2076    #[test]
2077    #[cfg(feature = "compiler")]
2078    fn parse_and_derive() {
2079        let descriptor_str = "thresh(2,\
2080pk([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*),\
2081pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1),\
2082pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
2083        let policy: policy::concrete::Policy<DescriptorPublicKey> = descriptor_str.parse().unwrap();
2084        let descriptor = Descriptor::<_, NoExt>::new_sh(policy.compile().unwrap()).unwrap();
2085        let definite_descriptor = descriptor.at_derivation_index(42).unwrap();
2086
2087        let res_descriptor_str = "thresh(2,\
2088pk([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/42),\
2089pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1),\
2090pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
2091        let res_policy: policy::concrete::Policy<DescriptorPublicKey> =
2092            res_descriptor_str.parse().unwrap();
2093        let res_descriptor =
2094            Descriptor::<DescriptorPublicKey, NoExt>::new_sh(res_policy.compile().unwrap())
2095                .unwrap();
2096
2097        assert_eq!(res_descriptor.to_string(), definite_descriptor.to_string());
2098    }
2099
2100    #[test]
2101    fn parse_with_secrets() {
2102        let secp = &secp256k1_zkp::Secp256k1::signing_only();
2103        let descriptor_str = "elwpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)#xldrpn5u";
2104        let (descriptor, keymap) =
2105            Descriptor::<DescriptorPublicKey>::parse_descriptor(secp, descriptor_str).unwrap();
2106
2107        let expected = "elwpkh([a12b02f4/44'/0'/0']xpub6BzhLAQUDcBUfHRQHZxDF2AbcJqp4Kaeq6bzJpXrjrWuK26ymTFwkEFbxPra2bJ7yeZKbDjfDeFwxe93JMqpo5SsPJH6dZdvV9kMzJkAZ69/0/*)#20ufqv7z";
2108        assert_eq!(expected, descriptor.to_string());
2109        assert_eq!(keymap.len(), 1);
2110
2111        // try to turn it back into a string with the secrets
2112        assert_eq!(descriptor_str, descriptor.to_string_with_secret(&keymap));
2113    }
2114
2115    #[test]
2116    fn checksum_for_nested_sh() {
2117        let descriptor_str = "elsh(wpkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL))";
2118        let descriptor: Descriptor<DescriptorPublicKey> = descriptor_str.parse().unwrap();
2119        assert_eq!(descriptor.to_string(), "elsh(wpkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL))#2040pn7l");
2120
2121        let descriptor_str = "elsh(wsh(pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))";
2122        let descriptor: Descriptor<DescriptorPublicKey> = descriptor_str.parse().unwrap();
2123        assert_eq!(descriptor.to_string(), "elsh(wsh(pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))#pqs0de7e");
2124    }
2125
2126    #[test]
2127    fn test_xonly_keys() {
2128        let comp_key = "0308c0fcf8895f4361b4fc77afe2ad53b0bd27dcebfd863421b2b246dc283d4103";
2129        let x_only_key = "08c0fcf8895f4361b4fc77afe2ad53b0bd27dcebfd863421b2b246dc283d4103";
2130
2131        // Both x-only keys and comp keys allowed in tr
2132        Descriptor::<DescriptorPublicKey>::from_str(&format!("eltr({})", comp_key)).unwrap();
2133        Descriptor::<DescriptorPublicKey>::from_str(&format!("eltr({})", x_only_key)).unwrap();
2134
2135        // Only compressed keys allowed in wsh
2136        Descriptor::<DescriptorPublicKey>::from_str(&format!("elwsh(pk({}))", comp_key)).unwrap();
2137        Descriptor::<DescriptorPublicKey>::from_str(&format!("elwsh(pk({}))", x_only_key))
2138            .unwrap_err();
2139    }
2140
2141    #[test]
2142    fn test_find_derivation_index_for_spk() {
2143        let secp = secp256k1_zkp::Secp256k1::verification_only();
2144        let descriptor = Descriptor::<_, NoExt>::from_str("eltr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)").unwrap();
2145        let script_at_0_1 = Script::from_str(
2146            "5120c73ac1b7a518499b9642aed8cfa15d5401e5bd85ad760b937b69521c297722f0",
2147        )
2148        .unwrap();
2149        let expected_concrete = Descriptor::from_str(
2150            "eltr(0283dfe85a3151d2517290da461fe2815591ef69f2b18a2ce63f01697a8b313145)",
2151        )
2152        .unwrap();
2153
2154        assert_eq!(
2155            descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..1),
2156            Ok(None)
2157        );
2158        assert_eq!(
2159            descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..2),
2160            Ok(Some((1, expected_concrete.clone())))
2161        );
2162        assert_eq!(
2163            descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..10),
2164            Ok(Some((1, expected_concrete)))
2165        );
2166    }
2167
2168    #[test]
2169    fn display_alternate() {
2170        let bare = StdDescriptor::from_str(
2171            "elpk(020000000000000000000000000000000000000000000000000000000000000002)",
2172        )
2173        .unwrap();
2174        assert_eq!(
2175            format!("{}", bare),
2176            "elpk(020000000000000000000000000000000000000000000000000000000000000002)#vlpqwfjv",
2177        );
2178        assert_eq!(
2179            format!("{:#}", bare),
2180            "elpk(020000000000000000000000000000000000000000000000000000000000000002)",
2181        );
2182
2183        let pkh = StdDescriptor::from_str(
2184            "elpkh(020000000000000000000000000000000000000000000000000000000000000002)",
2185        )
2186        .unwrap();
2187        assert_eq!(
2188            format!("{}", pkh),
2189            "elpkh(020000000000000000000000000000000000000000000000000000000000000002)#jzq8e832",
2190        );
2191        assert_eq!(
2192            format!("{:#}", pkh),
2193            "elpkh(020000000000000000000000000000000000000000000000000000000000000002)",
2194        );
2195
2196        let wpkh = StdDescriptor::from_str(
2197            "elwpkh(020000000000000000000000000000000000000000000000000000000000000002)",
2198        )
2199        .unwrap();
2200        assert_eq!(
2201            format!("{}", wpkh),
2202            "elwpkh(020000000000000000000000000000000000000000000000000000000000000002)#vxhqdpz9",
2203        );
2204        assert_eq!(
2205            format!("{:#}", wpkh),
2206            "elwpkh(020000000000000000000000000000000000000000000000000000000000000002)",
2207        );
2208
2209        let shwpkh = StdDescriptor::from_str(
2210            "elsh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))",
2211        )
2212        .unwrap();
2213        assert_eq!(
2214            format!("{}", shwpkh),
2215            "elsh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))#h9ajn2ft",
2216        );
2217        assert_eq!(
2218            format!("{:#}", shwpkh),
2219            "elsh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))",
2220        );
2221
2222        let wsh = StdDescriptor::from_str("elwsh(1)").unwrap();
2223        assert_eq!(format!("{}", wsh), "elwsh(1)#s78w5gmj");
2224        assert_eq!(format!("{:#}", wsh), "elwsh(1)");
2225
2226        let sh = StdDescriptor::from_str("elsh(1)").unwrap();
2227        assert_eq!(format!("{}", sh), "elsh(1)#k4aqrx5p");
2228        assert_eq!(format!("{:#}", sh), "elsh(1)");
2229
2230        let shwsh = StdDescriptor::from_str("elsh(wsh(1))").unwrap();
2231        assert_eq!(format!("{}", shwsh), "elsh(wsh(1))#d05z4wjl");
2232        assert_eq!(format!("{:#}", shwsh), "elsh(wsh(1))");
2233
2234        let tr = StdDescriptor::from_str(
2235            "eltr(020000000000000000000000000000000000000000000000000000000000000002)",
2236        )
2237        .unwrap();
2238        assert_eq!(
2239            format!("{}", tr),
2240            "eltr(020000000000000000000000000000000000000000000000000000000000000002)#e874qu8z",
2241        );
2242        assert_eq!(
2243            format!("{:#}", tr),
2244            "eltr(020000000000000000000000000000000000000000000000000000000000000002)",
2245        );
2246    }
2247
2248    #[test]
2249    fn test_regression_29() {
2250        let _ = Descriptor::<String>::from_str("eltr(,thresh(1,spk_eq(,00)))");
2251    }
2252
2253    #[test]
2254    fn multipath_descriptors() {
2255        // We can parse a multipath descriptors, and make it into separate single-path descriptors.
2256        let desc = Descriptor::<DescriptorPublicKey, NoExt>::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<7';8h;20>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/<0;1;987>/*)))").unwrap();
2257        assert!(desc.is_multipath());
2258        assert!(!desc.multipath_length_mismatch());
2259        assert_eq!(desc.into_single_descriptors().unwrap(), vec![
2260            Descriptor::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/7'/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/0/*)))").unwrap(),
2261            Descriptor::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/8h/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/1/*)))").unwrap(),
2262            Descriptor::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/20/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/987/*)))").unwrap()
2263        ]);
2264
2265        // Even if only one of the keys is multipath.
2266        let desc = Descriptor::<DescriptorPublicKey, NoExt>::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap();
2267        assert!(desc.is_multipath());
2268        assert!(!desc.multipath_length_mismatch());
2269        assert_eq!(desc.into_single_descriptors().unwrap(), vec![
2270            Descriptor::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/0/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap(),
2271            Descriptor::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/1/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap(),
2272        ]);
2273
2274        // We can detect regular single-path descriptors.
2275        let notmulti_desc = Descriptor::<DescriptorPublicKey, NoExt>::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap();
2276        assert!(!notmulti_desc.is_multipath());
2277        assert!(!notmulti_desc.multipath_length_mismatch());
2278        assert_eq!(
2279            notmulti_desc.clone().into_single_descriptors().unwrap(),
2280            vec![notmulti_desc]
2281        );
2282
2283        // We refuse to parse multipath descriptors with a mismatch in the number of derivation paths between keys.
2284        Descriptor::<DescriptorPublicKey>::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/<0;1;2;3;4>/*)))").unwrap_err();
2285        Descriptor::<DescriptorPublicKey>::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1;2;3>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/<0;1;2>/*)))").unwrap_err();
2286    }
2287}