Skip to main content

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::hashes::{hash160, ripemd160, sha256};
24use bitcoin::WitnessVersion;
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.into();
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`] for more documentation.
874    ///
875    /// [`at_derivation_index`]: Self::at_derivation_index
876    ///
877    /// # Errors
878    ///
879    /// This function will return an error if hardened derivation is attempted.
880    pub fn derived_descriptor<C: secp256k1_zkp::Verification>(
881        &self,
882        secp: &secp256k1_zkp::Secp256k1<C>,
883        index: u32,
884    ) -> Result<Descriptor<bitcoin::PublicKey, Ext>, ConversionError> {
885        self.at_derivation_index(index)?.derived_descriptor(secp)
886    }
887
888    /// Parse a descriptor that may contain secret keys
889    ///
890    /// Internally turns every secret key found into the corresponding public key and then returns a
891    /// a descriptor that only contains public keys and a map to lookup the secret key given a public key.
892    pub fn parse_descriptor<C: secp256k1_zkp::Signing>(
893        secp: &secp256k1_zkp::Secp256k1<C>,
894        s: &str,
895    ) -> Result<(Descriptor<DescriptorPublicKey, Ext>, KeyMap), Error> {
896        fn parse_key<C: secp256k1::Signing>(
897            s: &str,
898            key_map: &mut KeyMap,
899            secp: &secp256k1::Secp256k1<C>,
900        ) -> Result<DescriptorPublicKey, Error> {
901            let (public_key, secret_key) = match DescriptorSecretKey::from_str(s) {
902                Ok(sk) => (
903                    sk.to_public(secp)
904                        .map_err(|e| Error::Unexpected(e.to_string()))?,
905                    Some(sk),
906                ),
907                Err(_) => (
908                    DescriptorPublicKey::from_str(s)
909                        .map_err(|e| Error::Unexpected(e.to_string()))?,
910                    None,
911                ),
912            };
913
914            if let Some(secret_key) = secret_key {
915                key_map.insert(public_key.clone(), secret_key);
916            }
917
918            Ok(public_key)
919        }
920
921        let mut keymap_pk = KeyMapWrapper(HashMap::new(), secp);
922
923        struct KeyMapWrapper<'a, C: secp256k1::Signing>(KeyMap, &'a secp256k1::Secp256k1<C>);
924
925        impl<'a, C: secp256k1::Signing> Translator<String, DescriptorPublicKey, Error>
926            for KeyMapWrapper<'a, C>
927        {
928            fn pk(&mut self, pk: &String) -> Result<DescriptorPublicKey, Error> {
929                parse_key(pk, &mut self.0, self.1)
930            }
931
932            fn sha256(&mut self, sha256: &String) -> Result<sha256::Hash, Error> {
933                let hash =
934                    sha256::Hash::from_str(sha256).map_err(|e| Error::Unexpected(e.to_string()))?;
935                Ok(hash)
936            }
937
938            fn hash256(&mut self, hash256: &String) -> Result<hash256::Hash, Error> {
939                let hash = hash256::Hash::from_str(hash256)
940                    .map_err(|e| Error::Unexpected(e.to_string()))?;
941                Ok(hash)
942            }
943
944            fn ripemd160(&mut self, ripemd160: &String) -> Result<ripemd160::Hash, Error> {
945                let hash = ripemd160::Hash::from_str(ripemd160)
946                    .map_err(|e| Error::Unexpected(e.to_string()))?;
947                Ok(hash)
948            }
949
950            fn hash160(&mut self, hash160: &String) -> Result<hash160::Hash, Error> {
951                let hash = hash160::Hash::from_str(hash160)
952                    .map_err(|e| Error::Unexpected(e.to_string()))?;
953                Ok(hash)
954            }
955        }
956
957        let descriptor = Descriptor::<String, Ext>::from_str(s)?;
958        let descriptor = descriptor
959            .translate_pk(&mut keymap_pk)
960            .map_err(|e| Error::Unexpected(e.to_string()))?;
961
962        Ok((descriptor, keymap_pk.0))
963    }
964
965    /// Serialize a descriptor to string with its secret keys
966    pub fn to_string_with_secret(&self, key_map: &KeyMap) -> String {
967        struct KeyMapLookUp<'a>(&'a KeyMap);
968
969        impl<'a> Translator<DescriptorPublicKey, String, ()> for KeyMapLookUp<'a> {
970            fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<String, ()> {
971                Ok(key_to_string(pk, self.0))
972            }
973
974            fn sha256(&mut self, sha256: &sha256::Hash) -> Result<String, ()> {
975                Ok(sha256.to_string())
976            }
977
978            fn hash256(&mut self, hash256: &hash256::Hash) -> Result<String, ()> {
979                Ok(hash256.to_string())
980            }
981
982            fn ripemd160(&mut self, ripemd160: &ripemd160::Hash) -> Result<String, ()> {
983                Ok(ripemd160.to_string())
984            }
985
986            fn hash160(&mut self, hash160: &hash160::Hash) -> Result<String, ()> {
987                Ok(hash160.to_string())
988            }
989        }
990
991        fn key_to_string(pk: &DescriptorPublicKey, key_map: &KeyMap) -> String {
992            match key_map.get(pk) {
993                Some(secret) => secret.to_string(),
994                None => pk.to_string(),
995            }
996        }
997
998        let descriptor = self
999            .translate_pk(&mut KeyMapLookUp(key_map))
1000            .expect("Translation to string cannot fail");
1001
1002        descriptor.to_string()
1003    }
1004
1005    /// Whether this descriptor contains a key that has multiple derivation paths.
1006    pub fn is_multipath(&self) -> bool {
1007        self.for_any_key(DescriptorPublicKey::is_multipath)
1008    }
1009
1010    /// Get as many descriptors as different paths in this descriptor.
1011    ///
1012    /// For multipath descriptors it will return as many descriptors as there is
1013    /// "parallel" paths. For regular descriptors it will just return itself.
1014    pub fn into_single_descriptors(self) -> Result<Vec<Self>, Error> {
1015        // All single-path descriptors contained in this descriptor.
1016        let mut descriptors = Vec::new();
1017        // We (ab)use `for_any_key` to gather the number of separate descriptors.
1018        if !self.for_any_key(|key| {
1019            // All multipath keys must have the same number of indexes at the "multi-index"
1020            // step. So we can return early if we already populated the vector.
1021            if !descriptors.is_empty() {
1022                return true;
1023            }
1024
1025            match key {
1026                DescriptorPublicKey::Single(..) | DescriptorPublicKey::XPub(..) => false,
1027                DescriptorPublicKey::MultiXPub(xpub) => {
1028                    for _ in 0..xpub.derivation_paths.paths().len() {
1029                        descriptors.push(self.clone());
1030                    }
1031                    true
1032                }
1033            }
1034        }) {
1035            // If there is no multipath key, return early.
1036            return Ok(vec![self]);
1037        }
1038        assert!(!descriptors.is_empty());
1039
1040        // Now, transform the multipath key of each descriptor into a single-key using each index.
1041        struct IndexChoser(usize);
1042        impl Translator<DescriptorPublicKey, DescriptorPublicKey, Error> for IndexChoser {
1043            fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<DescriptorPublicKey, Error> {
1044                match pk {
1045                    DescriptorPublicKey::Single(..) | DescriptorPublicKey::XPub(..) => {
1046                        Ok(pk.clone())
1047                    }
1048                    DescriptorPublicKey::MultiXPub(_) => pk
1049                        .clone()
1050                        .into_single_keys()
1051                        .get(self.0)
1052                        .cloned()
1053                        .ok_or(Error::MultipathDescLenMismatch),
1054                }
1055            }
1056            translate_hash_clone!(DescriptorPublicKey, DescriptorPublicKey, Error);
1057        }
1058
1059        for (i, desc) in descriptors.iter_mut().enumerate() {
1060            let mut index_choser = IndexChoser(i);
1061            *desc = desc.translate_pk(&mut index_choser)?;
1062        }
1063
1064        Ok(descriptors)
1065    }
1066}
1067
1068impl<Ext: Extension + ParseableExt> Descriptor<DescriptorPublicKey, Ext> {
1069    /// Utility method for deriving the descriptor at each index in a range to find one matching
1070    /// `script_pubkey`.
1071    ///
1072    /// If it finds a match then it returns the index it was derived at and the concrete
1073    /// descriptor at that index. If the descriptor is non-derivable then it will simply check the
1074    /// script pubkey against the descriptor and return it if it matches (in this case the index
1075    /// returned will be meaningless).
1076    pub fn find_derivation_index_for_spk<C: secp256k1_zkp::Verification>(
1077        &self,
1078        secp: &secp256k1_zkp::Secp256k1<C>,
1079        script_pubkey: &Script,
1080        range: Range<u32>,
1081    ) -> Result<Option<(u32, Descriptor<bitcoin::PublicKey, Ext>)>, ConversionError> {
1082        let range = if self.has_wildcard() { range } else { 0..1 };
1083
1084        for i in range {
1085            let concrete = self.derived_descriptor(secp, i)?;
1086            if &concrete.script_pubkey() == script_pubkey {
1087                return Ok(Some((i, concrete)));
1088            }
1089        }
1090
1091        Ok(None)
1092    }
1093}
1094
1095impl<Pk: MiniscriptKey, Ext: Extension> Descriptor<Pk, Ext> {
1096    /// Whether this descriptor is a multipath descriptor that contains any 2 multipath keys
1097    /// with a different number of derivation paths.
1098    /// Such a descriptor is invalid according to BIP389.
1099    pub fn multipath_length_mismatch(&self) -> bool {
1100        // (Ab)use `for_each_key` to record the number of derivation paths a multipath key has.
1101        #[derive(PartialEq)]
1102        enum MultipathLenChecker {
1103            SinglePath,
1104            MultipathLen(usize),
1105            LenMismatch,
1106        }
1107
1108        let mut checker = MultipathLenChecker::SinglePath;
1109        self.for_each_key(|key| {
1110            match key.num_der_paths() {
1111                0 | 1 => {}
1112                n => match checker {
1113                    MultipathLenChecker::SinglePath => {
1114                        checker = MultipathLenChecker::MultipathLen(n);
1115                    }
1116                    MultipathLenChecker::MultipathLen(len) => {
1117                        if len != n {
1118                            checker = MultipathLenChecker::LenMismatch;
1119                        }
1120                    }
1121                    MultipathLenChecker::LenMismatch => {}
1122                },
1123            }
1124            true
1125        });
1126
1127        checker == MultipathLenChecker::LenMismatch
1128    }
1129}
1130
1131impl<Ext: Extension> Descriptor<DefiniteDescriptorKey, Ext> {
1132    /// Convert all the public keys in the descriptor to [`bitcoin::PublicKey`] by deriving them or
1133    /// otherwise converting them. All [`bitcoin::key::XOnlyPublicKey`]s are converted to by adding a
1134    /// default(0x02) y-coordinate.
1135    ///
1136    /// # Examples
1137    ///
1138    /// ```
1139    /// # extern crate elements_miniscript as miniscript;
1140    /// use miniscript::descriptor::{Descriptor, DescriptorPublicKey};
1141    /// use miniscript::bitcoin::secp256k1;
1142    /// use std::str::FromStr;
1143    ///
1144    /// // test from bip 86
1145    /// let secp = secp256k1::Secp256k1::verification_only();
1146    /// let descriptor = Descriptor::<DescriptorPublicKey>::from_str("eltr(xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)")
1147    ///     .expect("Valid ranged descriptor");
1148    /// let result = descriptor.at_derivation_index(0).unwrap().derived_descriptor(&secp).expect("Non-hardened derivation");
1149    /// assert_eq!(result.to_string(), "eltr(03cc8a4bc64d897bddc5fbc2f670f7a8ba0b386779106cf1223c6fc5d7cd6fc115)#hr5pt2wj");
1150    /// ```
1151    ///
1152    /// # Errors
1153    ///
1154    /// This function will return an error if hardened derivation is attempted.
1155    pub fn derived_descriptor<C: secp256k1::Verification>(
1156        &self,
1157        secp: &secp256k1::Secp256k1<C>,
1158    ) -> Result<Descriptor<bitcoin::PublicKey, Ext>, ConversionError> {
1159        struct Derivator<'a, C: secp256k1::Verification>(&'a secp256k1::Secp256k1<C>);
1160
1161        impl<'a, C: secp256k1::Verification>
1162            Translator<DefiniteDescriptorKey, bitcoin::PublicKey, ConversionError>
1163            for Derivator<'a, C>
1164        {
1165            fn pk(
1166                &mut self,
1167                pk: &DefiniteDescriptorKey,
1168            ) -> Result<bitcoin::PublicKey, ConversionError> {
1169                pk.derive_public_key(self.0)
1170            }
1171
1172            translate_hash_clone!(DefiniteDescriptorKey, bitcoin::PublicKey, ConversionError);
1173        }
1174
1175        let derived = self.translate_pk(&mut Derivator(secp))?;
1176        Ok(derived)
1177    }
1178}
1179
1180impl_from_tree!(
1181    ;T; Extension,
1182    Descriptor<Pk, T>,
1183    /// Parse an expression tree into a descriptor.
1184    fn from_tree(top: &expression::Tree) -> Result<Descriptor<Pk, T>, Error> {
1185        Ok(match (top.name, top.args.len() as u32) {
1186            ("elpkh", 1) => Descriptor::Pkh(Pkh::from_tree(top)?),
1187            ("elwpkh", 1) => Descriptor::Wpkh(Wpkh::from_tree(top)?),
1188            ("elsh", 1) => Descriptor::Sh(Sh::from_tree(top)?),
1189            ("elcovwsh", 2) => Descriptor::LegacyCSFSCov(LegacyCSFSCov::from_tree(top)?),
1190            ("elwsh", 1) => Descriptor::Wsh(Wsh::from_tree(top)?),
1191            ("eltr", _) => Descriptor::Tr(Tr::from_tree(top)?),
1192            _ => Descriptor::Bare(Bare::from_tree(top)?),
1193        })
1194    }
1195);
1196
1197impl_from_str!(
1198    ;T; Extension,
1199    Descriptor<Pk, T>,
1200    type Err = Error;,
1201    fn from_str(s: &str) -> Result<Descriptor<Pk, T>, Error> {
1202        if !s.starts_with(ELMTS_STR) {
1203            return Err(Error::BadDescriptor(String::from(
1204                "Not an Elements Descriptor",
1205            )));
1206        }
1207        // tr tree parsing has special code
1208        // Tr::from_str will check the checksum
1209        // match "tr(" to handle more extensibly
1210        let desc = if s.starts_with(&format!("{}tr", ELMTS_STR)) {
1211            // First try parsing without extensions
1212            match Tr::<Pk, NoExt>::from_str(s) {
1213                Ok(tr) => Descriptor::Tr(tr),
1214                Err(_) => {
1215                    // Try parsing with extensions
1216                    let tr = Tr::<Pk, T>::from_str(s)?;
1217                    Descriptor::TrExt(tr)
1218                }
1219            }
1220        } else {
1221            let desc_str = verify_checksum(s)?;
1222            let top = expression::Tree::from_str(desc_str)?;
1223            expression::FromTree::from_tree(&top)?
1224        };
1225
1226        if desc.multipath_length_mismatch() {
1227            return Err(Error::MultipathDescLenMismatch);
1228        }
1229
1230        Ok(desc)
1231    }
1232);
1233
1234impl<Pk: MiniscriptKey, T: Extension> fmt::Debug for Descriptor<Pk, T> {
1235    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1236        match *self {
1237            Descriptor::Bare(ref sub) => fmt::Debug::fmt(sub, f),
1238            Descriptor::Pkh(ref pkh) => fmt::Debug::fmt(pkh, f),
1239            Descriptor::Wpkh(ref wpkh) => fmt::Debug::fmt(wpkh, f),
1240            Descriptor::Sh(ref sub) => fmt::Debug::fmt(sub, f),
1241            Descriptor::Wsh(ref sub) => fmt::Debug::fmt(sub, f),
1242            Descriptor::Tr(ref tr) => fmt::Debug::fmt(tr, f),
1243            Descriptor::TrExt(ref tr) => fmt::Debug::fmt(tr, f),
1244            Descriptor::LegacyCSFSCov(ref cov) => fmt::Debug::fmt(cov, f),
1245        }
1246    }
1247}
1248
1249impl<Pk: MiniscriptKey, T: Extension> fmt::Display for Descriptor<Pk, T> {
1250    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1251        match *self {
1252            Descriptor::Bare(ref sub) => fmt::Display::fmt(sub, f),
1253            Descriptor::Pkh(ref pkh) => fmt::Display::fmt(pkh, f),
1254            Descriptor::Wpkh(ref wpkh) => fmt::Display::fmt(wpkh, f),
1255            Descriptor::Sh(ref sub) => fmt::Display::fmt(sub, f),
1256            Descriptor::Wsh(ref sub) => fmt::Display::fmt(sub, f),
1257            Descriptor::Tr(ref tr) => fmt::Display::fmt(tr, f),
1258            Descriptor::TrExt(ref tr) => fmt::Display::fmt(tr, f),
1259            Descriptor::LegacyCSFSCov(ref cov) => fmt::Display::fmt(cov, f),
1260        }
1261    }
1262}
1263
1264serde_string_impl_pk!(Descriptor, "a script descriptor", T; Extension);
1265
1266#[cfg(test)]
1267mod tests {
1268    use std::collections::HashMap;
1269    use std::str::FromStr;
1270
1271    use bitcoin;
1272    use bitcoin::hashes::{hash160, sha256};
1273    use bitcoin::hex::{DisplayHex, FromHex};
1274    use bitcoin::{bip32, PublicKey};
1275    use elements::opcodes::all::{OP_CLTV, OP_CSV};
1276    use elements::script::Instruction;
1277    use elements::{opcodes, script, Sequence};
1278
1279    use super::checksum::desc_checksum;
1280    use super::tr::Tr;
1281    use super::*;
1282    use crate::descriptor::key::Wildcard;
1283    use crate::descriptor::{DescriptorPublicKey, DescriptorXKey};
1284    use crate::miniscript::satisfy::ElementsSig;
1285    #[cfg(feature = "compiler")]
1286    use crate::policy;
1287    use crate::{hex_script, Descriptor, Error, Miniscript, NoExt, Satisfier};
1288
1289    type StdDescriptor = Descriptor<PublicKey, CovenantExt<CovExtArgs>>;
1290    const TEST_PK: &str =
1291        "elpk(020000000000000000000000000000000000000000000000000000000000000002)";
1292
1293    fn roundtrip_descriptor(s: &str) {
1294        let desc = Descriptor::<String>::from_str(s).unwrap();
1295        let output = desc.to_string();
1296        let normalize_aliases = s.replace("c:pk_k(", "pk(").replace("c:pk_h(", "pkh(");
1297        assert_eq!(
1298            format!(
1299                "{}#{}",
1300                &normalize_aliases,
1301                desc_checksum(&normalize_aliases).unwrap()
1302            ),
1303            output
1304        );
1305    }
1306
1307    // helper function to create elements txin from scriptsig and witness
1308    fn elements_txin(script_sig: Script, witness: Vec<Vec<u8>>) -> elements::TxIn {
1309        let txin_witness = elements::TxInWitness {
1310            script_witness: witness.into(),
1311            ..Default::default()
1312        };
1313        elements::TxIn {
1314            previous_output: elements::OutPoint::default(),
1315            script_sig,
1316            sequence: Sequence::from_height(100),
1317            is_pegin: false,
1318            asset_issuance: elements::AssetIssuance::default(),
1319            witness: txin_witness,
1320        }
1321    }
1322
1323    #[test]
1324    fn desc_rtt_tests() {
1325        roundtrip_descriptor("elc:pk_k()");
1326        roundtrip_descriptor("elwsh(pk())");
1327        roundtrip_descriptor("elwsh(c:pk_k())");
1328        roundtrip_descriptor("elc:pk_h()");
1329    }
1330    #[test]
1331    fn parse_descriptor() {
1332        StdDescriptor::from_str("(").unwrap_err();
1333        StdDescriptor::from_str("(x()").unwrap_err();
1334        StdDescriptor::from_str("(\u{7f}()3").unwrap_err();
1335        StdDescriptor::from_str("pk()").unwrap_err();
1336        StdDescriptor::from_str("nl:0").unwrap_err(); //issue 63
1337        let compressed_pk = "02be5645686309c6e6736dbd93940707cc9143d3cf29f1b877ff340e2cb2d259cf";
1338        assert_eq!(
1339            StdDescriptor::from_str("elsh(sortedmulti)")
1340                .unwrap_err()
1341                .to_string(),
1342            "unexpected «no arguments given for sortedmulti»"
1343        ); //issue 202
1344        assert_eq!(
1345            StdDescriptor::from_str(&format!("elsh(sortedmulti(2,{}))", compressed_pk))
1346                .unwrap_err()
1347                .to_string(),
1348            "unexpected «higher threshold than there were keys in sortedmulti»"
1349        ); //issue 202
1350
1351        StdDescriptor::from_str(TEST_PK).unwrap();
1352        // fuzzer
1353        StdDescriptor::from_str("slip77").unwrap_err();
1354
1355        let uncompressed_pk =
1356        "0414fc03b8df87cd7b872996810db8458d61da8448e531569c8517b469a119d267be5645686309c6e6736dbd93940707cc9143d3cf29f1b877ff340e2cb2d259cf";
1357
1358        // Context tests
1359        StdDescriptor::from_str(&format!("elpk({})", uncompressed_pk)).unwrap();
1360        StdDescriptor::from_str(&format!("elpkh({})", uncompressed_pk)).unwrap();
1361        StdDescriptor::from_str(&format!("elsh(pk({}))", uncompressed_pk)).unwrap();
1362        StdDescriptor::from_str(&format!("elwpkh({})", uncompressed_pk)).unwrap_err();
1363        StdDescriptor::from_str(&format!("elsh(wpkh({}))", uncompressed_pk)).unwrap_err();
1364        StdDescriptor::from_str(&format!("elwsh(pk{})", uncompressed_pk)).unwrap_err();
1365        StdDescriptor::from_str(&format!("elsh(wsh(pk{}))", uncompressed_pk)).unwrap_err();
1366        StdDescriptor::from_str(&format!(
1367            "elor_i(pk({}),pk({}))",
1368            uncompressed_pk, uncompressed_pk
1369        ))
1370        .unwrap_err();
1371    }
1372
1373    #[test]
1374    pub fn script_pubkey() {
1375        let bare = StdDescriptor::from_str(
1376            "elmulti(1,020000000000000000000000000000000000000000000000000000000000000002)",
1377        )
1378        .unwrap();
1379        assert_eq!(
1380            bare.script_pubkey(),
1381            hex_script(
1382                "512102000000000000000000000000000000000000000000000000000000000000000251ae"
1383            )
1384        );
1385        assert_eq!(
1386            bare.address(&elements::AddressParams::ELEMENTS)
1387                .unwrap_err()
1388                .to_string(),
1389            "Bare descriptors don't have address"
1390        );
1391
1392        let pk = StdDescriptor::from_str(TEST_PK).unwrap();
1393        assert_eq!(
1394            pk.script_pubkey(),
1395            elements::Script::from(vec![
1396                0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1397                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1398                0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xac,
1399            ])
1400        );
1401
1402        let pkh = StdDescriptor::from_str(
1403            "elpkh(\
1404             020000000000000000000000000000000000000000000000000000000000000002\
1405             )",
1406        )
1407        .unwrap();
1408        assert_eq!(
1409            pkh.script_pubkey(),
1410            script::Builder::new()
1411                .push_opcode(opcodes::all::OP_DUP)
1412                .push_opcode(opcodes::all::OP_HASH160)
1413                .push_slice(
1414                    &hash160::Hash::from_str("84e9ed95a38613f0527ff685a9928abe2d4754d4",).unwrap()
1415                        [..]
1416                )
1417                .push_opcode(opcodes::all::OP_EQUALVERIFY)
1418                .push_opcode(opcodes::all::OP_CHECKSIG)
1419                .into_script()
1420        );
1421        assert_eq!(
1422            pkh.address(&elements::AddressParams::ELEMENTS,)
1423                .unwrap()
1424                .to_string(),
1425            "2dmYXpSu8YP6aLcJYhHfB1C19mdzSx2GPB9"
1426        );
1427
1428        let wpkh = StdDescriptor::from_str(
1429            "elwpkh(\
1430             020000000000000000000000000000000000000000000000000000000000000002\
1431             )",
1432        )
1433        .unwrap();
1434        assert_eq!(
1435            wpkh.script_pubkey(),
1436            script::Builder::new()
1437                .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1438                .push_slice(
1439                    &hash160::Hash::from_str("84e9ed95a38613f0527ff685a9928abe2d4754d4",).unwrap()
1440                        [..]
1441                )
1442                .into_script()
1443        );
1444        assert_eq!(
1445            wpkh.address(&elements::AddressParams::ELEMENTS,)
1446                .unwrap()
1447                .to_string(),
1448            "ert1qsn57m9drscflq5nl76z6ny52hck5w4x57m69k3"
1449        );
1450
1451        let shwpkh = StdDescriptor::from_str(
1452            "elsh(wpkh(\
1453             020000000000000000000000000000000000000000000000000000000000000002\
1454             ))",
1455        )
1456        .unwrap();
1457        assert_eq!(
1458            shwpkh.script_pubkey(),
1459            script::Builder::new()
1460                .push_opcode(opcodes::all::OP_HASH160)
1461                .push_slice(
1462                    &hash160::Hash::from_str("f1c3b9a431134cb90a500ec06e0067cfa9b8bba7",).unwrap()
1463                        [..]
1464                )
1465                .push_opcode(opcodes::all::OP_EQUAL)
1466                .into_script()
1467        );
1468        assert_eq!(
1469            shwpkh
1470                .address(&elements::AddressParams::ELEMENTS,)
1471                .unwrap()
1472                .to_string(),
1473            "XZPaAbg6M83Fq5NqvbEGZ5kwy9RKSTke2s"
1474        );
1475
1476        let sh = StdDescriptor::from_str(
1477            "elsh(c:pk_k(\
1478             020000000000000000000000000000000000000000000000000000000000000002\
1479             ))",
1480        )
1481        .unwrap();
1482        assert_eq!(
1483            sh.script_pubkey(),
1484            script::Builder::new()
1485                .push_opcode(opcodes::all::OP_HASH160)
1486                .push_slice(
1487                    &hash160::Hash::from_str("aa5282151694d3f2f32ace7d00ad38f927a33ac8",).unwrap()
1488                        [..]
1489                )
1490                .push_opcode(opcodes::all::OP_EQUAL)
1491                .into_script()
1492        );
1493        assert_eq!(
1494            sh.address(&elements::AddressParams::ELEMENTS,)
1495                .unwrap()
1496                .to_string(),
1497            "XSspZXDJu2XVh8AKC7qF3L7x79Qy67JhQb"
1498        );
1499
1500        let wsh = StdDescriptor::from_str(
1501            "elwsh(c:pk_k(\
1502             020000000000000000000000000000000000000000000000000000000000000002\
1503             ))",
1504        )
1505        .unwrap();
1506        assert_eq!(
1507            wsh.script_pubkey(),
1508            script::Builder::new()
1509                .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1510                .push_slice(
1511                    &sha256::Hash::from_str(
1512                        "\
1513                         f9379edc8983152dc781747830075bd5\
1514                         3896e4b0ce5bff73777fd77d124ba085\
1515                         "
1516                    )
1517                    .unwrap()[..]
1518                )
1519                .into_script()
1520        );
1521        assert_eq!(
1522            wsh.address(&elements::AddressParams::ELEMENTS,)
1523                .unwrap()
1524                .to_string(),
1525            "ert1qlymeahyfsv2jm3upw3urqp6m65ufde9seedl7umh0lth6yjt5zzsan9u2t"
1526        );
1527
1528        let shwsh = StdDescriptor::from_str(
1529            "elsh(wsh(c:pk_k(\
1530             020000000000000000000000000000000000000000000000000000000000000002\
1531             )))",
1532        )
1533        .unwrap();
1534        assert_eq!(
1535            shwsh.script_pubkey(),
1536            script::Builder::new()
1537                .push_opcode(opcodes::all::OP_HASH160)
1538                .push_slice(
1539                    &hash160::Hash::from_str("4bec5d7feeed99e1d0a23fe32a4afe126a7ff07e",).unwrap()
1540                        [..]
1541                )
1542                .push_opcode(opcodes::all::OP_EQUAL)
1543                .into_script()
1544        );
1545        assert_eq!(
1546            shwsh
1547                .address(&elements::AddressParams::ELEMENTS,)
1548                .unwrap()
1549                .to_string(),
1550            "XJGggUb965TvGF2VCxp9EQGmZTxMeDjwQQ"
1551        );
1552    }
1553
1554    #[test]
1555    fn satisfy() {
1556        let secp = secp256k1_zkp::Secp256k1::new();
1557        let sk =
1558            secp256k1_zkp::SecretKey::from_slice(&b"sally was a secret key, she said"[..]).unwrap();
1559        let pk = bitcoin::PublicKey {
1560            inner: secp256k1_zkp::PublicKey::from_secret_key(&secp, &sk),
1561            compressed: true,
1562        };
1563        let msg =
1564            secp256k1_zkp::Message::from_digest_slice(&b"michael was a message, amusingly"[..])
1565                .expect("32 bytes");
1566        let sig = secp.sign_ecdsa(&msg, &sk);
1567        let mut sigser = sig.serialize_der().to_vec();
1568        sigser.push(0x01); // sighash_all
1569
1570        struct SimpleSat {
1571            sig: secp256k1_zkp::ecdsa::Signature,
1572            pk: bitcoin::PublicKey,
1573        }
1574
1575        impl Satisfier<bitcoin::PublicKey> for SimpleSat {
1576            fn lookup_ecdsa_sig(&self, pk: &bitcoin::PublicKey) -> Option<ElementsSig> {
1577                if *pk == self.pk {
1578                    Some((self.sig, elements::EcdsaSighashType::All))
1579                } else {
1580                    None
1581                }
1582            }
1583        }
1584
1585        let satisfier = SimpleSat { sig, pk };
1586        let ms = ms_str!("c:pk_k({})", pk);
1587
1588        let mut txin = elements::TxIn {
1589            previous_output: elements::OutPoint::default(),
1590            script_sig: Script::new(),
1591            sequence: Sequence::from_height(100),
1592            is_pegin: false,
1593            asset_issuance: elements::AssetIssuance::default(),
1594            witness: elements::TxInWitness::default(),
1595        };
1596        let bare: Descriptor<_, NoExt> = Descriptor::new_bare(ms).unwrap();
1597
1598        bare.satisfy(&mut txin, &satisfier).expect("satisfaction");
1599        assert_eq!(
1600            txin,
1601            elements_txin(
1602                script::Builder::new().push_slice(&sigser[..]).into_script(),
1603                vec![]
1604            ),
1605        );
1606        assert_eq!(bare.unsigned_script_sig(), elements::Script::new());
1607
1608        let pkh: Descriptor<_, NoExt> = Descriptor::new_pkh(pk);
1609        pkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1610        assert_eq!(
1611            txin,
1612            elements_txin(
1613                script::Builder::new()
1614                    .push_slice(&sigser[..])
1615                    .push_key(&pk)
1616                    .into_script(),
1617                vec![]
1618            )
1619        );
1620        assert_eq!(pkh.unsigned_script_sig(), elements::Script::new());
1621
1622        let wpkh: Descriptor<_, NoExt> = Descriptor::new_wpkh(pk).unwrap();
1623        wpkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1624        assert_eq!(
1625            txin,
1626            elements_txin(Script::new(), vec![sigser.clone(), pk.to_bytes(),])
1627        );
1628        assert_eq!(wpkh.unsigned_script_sig(), elements::Script::new());
1629
1630        let shwpkh: Descriptor<_, NoExt> = Descriptor::new_sh_wpkh(pk).unwrap();
1631        shwpkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1632        let redeem_script = script::Builder::new()
1633            .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1634            .push_slice(
1635                &hash160::Hash::from_str("d1b2a1faf62e73460af885c687dee3b7189cd8ab").unwrap()[..],
1636            )
1637            .into_script();
1638        let expected_ssig = script::Builder::new()
1639            .push_slice(&redeem_script[..])
1640            .into_script();
1641        assert_eq!(
1642            txin,
1643            elements_txin(expected_ssig.clone(), vec![sigser.clone(), pk.to_bytes()])
1644        );
1645        assert_eq!(shwpkh.unsigned_script_sig(), expected_ssig);
1646
1647        let ms = ms_str!("c:pk_k({})", pk);
1648        let sh: Descriptor<_, NoExt> = Descriptor::new_sh(ms.clone()).unwrap();
1649        sh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1650        let expected_ssig = script::Builder::new()
1651            .push_slice(&sigser[..])
1652            .push_slice(&ms.encode()[..])
1653            .into_script();
1654        assert_eq!(txin, elements_txin(expected_ssig, vec![]));
1655        assert_eq!(sh.unsigned_script_sig(), Script::new());
1656
1657        let ms = ms_str!("c:pk_k({})", pk);
1658
1659        let wsh: Descriptor<_, NoExt> = Descriptor::new_wsh(ms.clone()).unwrap();
1660        wsh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1661        assert_eq!(
1662            txin,
1663            elements_txin(
1664                Script::new(),
1665                vec![sigser.clone(), ms.encode().into_bytes()]
1666            )
1667        );
1668        assert_eq!(wsh.unsigned_script_sig(), Script::new());
1669
1670        let shwsh: Descriptor<_, NoExt> = Descriptor::new_sh_wsh(ms.clone()).unwrap();
1671        shwsh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1672        let expected_ssig = script::Builder::new()
1673            .push_slice(&ms.encode().to_v0_p2wsh()[..])
1674            .into_script();
1675        assert_eq!(
1676            txin,
1677            elements_txin(
1678                expected_ssig.clone(),
1679                vec![sigser.clone(), ms.encode().into_bytes(),]
1680            )
1681        );
1682        assert_eq!(shwsh.unsigned_script_sig(), expected_ssig);
1683    }
1684
1685    #[test]
1686    fn after_is_cltv() {
1687        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("elwsh(after(1000))").unwrap();
1688        let script = descriptor.explicit_script().unwrap();
1689
1690        let actual_instructions: Vec<_> = script.instructions().collect();
1691        let check = actual_instructions.last().unwrap();
1692
1693        assert_eq!(check, &Ok(Instruction::Op(OP_CLTV)))
1694    }
1695
1696    #[test]
1697    fn older_is_csv() {
1698        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("elwsh(older(1000))").unwrap();
1699        let script = descriptor.explicit_script().unwrap();
1700
1701        let actual_instructions: Vec<_> = script.instructions().collect();
1702        let check = actual_instructions.last().unwrap();
1703
1704        assert_eq!(check, &Ok(Instruction::Op(OP_CSV)))
1705    }
1706
1707    #[test]
1708    fn tr_roundtrip_key() {
1709        let script = Tr::<String>::from_str("eltr()").unwrap().to_string();
1710        assert_eq!(script, format!("eltr()#sux3r82e"))
1711    }
1712
1713    #[test]
1714    fn tr_roundtrip_script() {
1715        let descriptor = Tr::<String>::from_str("eltr(,{pk(),pk()})")
1716            .unwrap()
1717            .to_string();
1718
1719        assert_eq!(descriptor, "eltr(,{pk(),pk()})#lxgcxh02");
1720
1721        let descriptor = Descriptor::<String>::from_str("eltr(A,{pk(B),pk(C)})")
1722            .unwrap()
1723            .to_string();
1724        assert_eq!(descriptor, "eltr(A,{pk(B),pk(C)})#cx98s50f");
1725    }
1726
1727    #[test]
1728    fn tr_roundtrip_tree() {
1729        let p1 = "020000000000000000000000000000000000000000000000000000000000000001";
1730        let p2 = "020000000000000000000000000000000000000000000000000000000000000002";
1731        let p3 = "020000000000000000000000000000000000000000000000000000000000000003";
1732        let p4 = "020000000000000000000000000000000000000000000000000000000000000004";
1733        let p5 = "03f8551772d66557da28c1de858124f365a8eb30ce6ad79c10e0f4c546d0ab0f82";
1734        let descriptor = Tr::<PublicKey>::from_str(&format!(
1735            "eltr({},{{pk({}),{{pk({}),or_d(pk({}),pkh({}))}}}})",
1736            p1, p2, p3, p4, p5
1737        ))
1738        .unwrap()
1739        .to_string();
1740
1741        // p5.to_pubkeyhash() = 516ca378e588a7ed71336147e2a72848b20aca1a
1742        assert_eq!(
1743            descriptor,
1744            format!(
1745                "eltr({},{{pk({}),{{pk({}),or_d(pk({}),pkh({}))}}}})#y9kzzx3w",
1746                p1, p2, p3, p4, p5
1747            )
1748        )
1749    }
1750
1751    #[test]
1752    fn tr_script_pubkey() {
1753        let key = Descriptor::<bitcoin::PublicKey>::from_str(
1754            "eltr(02e20e746af365e86647826397ba1c0e0d5cb685752976fe2f326ab76bdc4d6ee9)",
1755        )
1756        .unwrap();
1757        assert_eq!(
1758            key.script_pubkey().as_bytes().to_lower_hex_string(),
1759            "51203f48e7c6203a75722733e3d9d06638da38d946066159c64684caf1622b2b0e33"
1760        )
1761    }
1762
1763    #[test]
1764    fn roundtrip_tests() {
1765        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("elmulti");
1766        assert_eq!(
1767            descriptor.unwrap_err().to_string(),
1768            "unexpected «no arguments given»"
1769        )
1770    }
1771
1772    #[test]
1773    fn empty_thresh() {
1774        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("elthresh");
1775        assert_eq!(
1776            descriptor.unwrap_err().to_string(),
1777            "unexpected «no arguments given»"
1778        )
1779    }
1780
1781    #[test]
1782    fn witness_stack_for_andv_is_arranged_in_correct_order() {
1783        // arrange
1784        let a = bitcoin::PublicKey::from_str(
1785            "02937402303919b3a2ee5edd5009f4236f069bf75667b8e6ecf8e5464e20116a0e",
1786        )
1787        .unwrap();
1788        let sig_a = secp256k1_zkp::ecdsa::Signature::from_str("3045022100a7acc3719e9559a59d60d7b2837f9842df30e7edcd754e63227e6168cec72c5d022066c2feba4671c3d99ea75d9976b4da6c86968dbf3bab47b1061e7a1966b1778c").unwrap();
1789
1790        let b = bitcoin::PublicKey::from_str(
1791            "02eb64639a17f7334bb5a1a3aad857d6fec65faef439db3de72f85c88bc2906ad3",
1792        )
1793        .unwrap();
1794        let sig_b = secp256k1_zkp::ecdsa::Signature::from_str("3044022075b7b65a7e6cd386132c5883c9db15f9a849a0f32bc680e9986398879a57c276022056d94d12255a4424f51c700ac75122cb354895c9f2f88f0cbb47ba05c9c589ba").unwrap();
1795
1796        let descriptor = Descriptor::<bitcoin::PublicKey>::from_str(&format!(
1797            "elwsh(and_v(v:pk({A}),pk({B})))",
1798            A = a,
1799            B = b
1800        ))
1801        .unwrap();
1802
1803        let mut txin = elements_txin(Script::new(), vec![]);
1804        let satisfier = {
1805            let mut satisfier = HashMap::with_capacity(2);
1806
1807            satisfier.insert(a, (sig_a, ::elements::EcdsaSighashType::All));
1808            satisfier.insert(b, (sig_b, ::elements::EcdsaSighashType::All));
1809
1810            satisfier
1811        };
1812
1813        // act
1814        descriptor.satisfy(&mut txin, &satisfier).unwrap();
1815
1816        // assert
1817        let witness0 = &txin.witness.script_witness[0];
1818        let witness1 = &txin.witness.script_witness[1];
1819
1820        let sig0 =
1821            secp256k1_zkp::ecdsa::Signature::from_der(&witness0[..witness0.len() - 1]).unwrap();
1822        let sig1 =
1823            secp256k1_zkp::ecdsa::Signature::from_der(&witness1[..witness1.len() - 1]).unwrap();
1824
1825        // why are we asserting this way?
1826        // The witness stack is evaluated from top to bottom. Given an `and` instruction, the left arm of the and is going to evaluate first,
1827        // 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`.
1828        // 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`.
1829        assert_eq!(sig1, sig_a);
1830        assert_eq!(sig0, sig_b);
1831    }
1832
1833    #[test]
1834    fn test_scriptcode() {
1835        // P2WPKH (from bip143 test vectors)
1836        let descriptor = Descriptor::<PublicKey>::from_str(
1837            "elwpkh(025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357)",
1838        )
1839        .unwrap();
1840        assert_eq!(
1841            *descriptor.script_code().unwrap().as_bytes(),
1842            Vec::<u8>::from_hex("76a9141d0f172a0ecb48aee1be1f2687d2963ae33f71a188ac").unwrap()[..]
1843        );
1844
1845        // P2SH-P2WPKH (from bip143 test vectors)
1846        let descriptor = Descriptor::<PublicKey>::from_str(
1847            "elsh(wpkh(03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873))",
1848        )
1849        .unwrap();
1850        assert_eq!(
1851            *descriptor.script_code().unwrap().as_bytes(),
1852            Vec::<u8>::from_hex("76a91479091972186c449eb1ded22b78e40d009bdf008988ac").unwrap()[..]
1853        );
1854
1855        // P2WSH (from bitcoind's `createmultisig`)
1856        let descriptor = Descriptor::<PublicKey>::from_str(
1857            "elwsh(multi(2,03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd,03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626))",
1858        )
1859        .unwrap();
1860        assert_eq!(
1861            *descriptor
1862                .script_code().unwrap()
1863                .as_bytes(),
1864            Vec::<u8>::from_hex("522103789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd2103dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a6162652ae").unwrap()[..]
1865        );
1866
1867        // P2SH-P2WSH (from bitcoind's `createmultisig`)
1868        let descriptor = Descriptor::<PublicKey>::from_str("elsh(wsh(multi(2,03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd,03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626)))").unwrap();
1869        assert_eq!(
1870            *descriptor
1871                .script_code().unwrap()
1872                .as_bytes(),
1873            Vec::<u8>::from_hex("522103789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd2103dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a6162652ae")
1874                .unwrap()[..]
1875        );
1876    }
1877
1878    #[test]
1879    fn parse_descriptor_key() {
1880        // With a wildcard
1881        let key = "[78412e3a/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*";
1882        let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1883            origin: Some((
1884                bip32::Fingerprint::from([0x78, 0x41, 0x2e, 0x3a]),
1885                (&[
1886                    bip32::ChildNumber::from_hardened_idx(44).unwrap(),
1887                    bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1888                    bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1889                ][..])
1890                .into(),
1891            )),
1892            xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1893            derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1894            wildcard: Wildcard::Unhardened,
1895        });
1896        assert_eq!(expected, key.parse().unwrap());
1897        assert_eq!(format!("{}", expected), key);
1898
1899        // Without origin
1900        let key = "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1";
1901        let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1902            origin: None,
1903            xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1904            derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1905            wildcard: Wildcard::None,
1906        });
1907        assert_eq!(expected, key.parse().unwrap());
1908        assert_eq!(format!("{}", expected), key);
1909
1910        // Testnet tpub
1911        let key = "tpubD6NzVbkrYhZ4YqYr3amYH15zjxHvBkUUeadieW8AxTZC7aY2L8aPSk3tpW6yW1QnWzXAB7zoiaNMfwXPPz9S68ZCV4yWvkVXjdeksLskCed/1";
1912        let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1913            origin: None,
1914            xkey: bip32::Xpub::from_str("tpubD6NzVbkrYhZ4YqYr3amYH15zjxHvBkUUeadieW8AxTZC7aY2L8aPSk3tpW6yW1QnWzXAB7zoiaNMfwXPPz9S68ZCV4yWvkVXjdeksLskCed").unwrap(),
1915            derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1916            wildcard: Wildcard::None,
1917        });
1918        assert_eq!(expected, key.parse().unwrap());
1919        assert_eq!(format!("{}", expected), key);
1920
1921        // Without derivation path
1922        let key = "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL";
1923        let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1924            origin: None,
1925            xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1926            derivation_path: bip32::DerivationPath::from(&[][..]),
1927            wildcard: Wildcard::None,
1928        });
1929        assert_eq!(expected, key.parse().unwrap());
1930        assert_eq!(format!("{}", expected), key);
1931
1932        // Raw (compressed) pubkey
1933        let key = "03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8";
1934        let expected = DescriptorPublicKey::Single(SinglePub {
1935            key: SinglePubKey::FullKey(
1936                bitcoin::PublicKey::from_str(
1937                    "03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8",
1938                )
1939                .unwrap(),
1940            ),
1941            origin: None,
1942        });
1943        assert_eq!(expected, key.parse().unwrap());
1944        assert_eq!(format!("{}", expected), key);
1945
1946        // Raw (uncompressed) pubkey
1947        let key = "04f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446a";
1948        let expected = DescriptorPublicKey::Single(SinglePub {
1949            key: SinglePubKey::FullKey(bitcoin::PublicKey::from_str(
1950                "04f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446a",
1951            )
1952            .unwrap()),
1953            origin: None,
1954        });
1955        assert_eq!(expected, key.parse().unwrap());
1956        assert_eq!(format!("{}", expected), key);
1957
1958        // Raw pubkey with origin
1959        let desc =
1960            "[78412e3a/0'/42/0']0231c7d3fc85c148717848033ce276ae2b464a4e2c367ed33886cc428b8af48ff8";
1961        let expected = DescriptorPublicKey::Single(SinglePub {
1962            key: SinglePubKey::FullKey(
1963                bitcoin::PublicKey::from_str(
1964                    "0231c7d3fc85c148717848033ce276ae2b464a4e2c367ed33886cc428b8af48ff8",
1965                )
1966                .unwrap(),
1967            ),
1968            origin: Some((
1969                bip32::Fingerprint::from([0x78, 0x41, 0x2e, 0x3a]),
1970                (&[
1971                    bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1972                    bip32::ChildNumber::from_normal_idx(42).unwrap(),
1973                    bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1974                ][..])
1975                    .into(),
1976            )),
1977        });
1978        assert_eq!(expected, desc.parse().expect("Parsing desc"));
1979        assert_eq!(format!("{}", expected), desc);
1980    }
1981
1982    #[test]
1983    fn test_sortedmulti() {
1984        fn _test_sortedmulti(raw_desc_one: &str, raw_desc_two: &str, raw_addr_expected: &str) {
1985            let secp_ctx = secp256k1_zkp::Secp256k1::verification_only();
1986            let index = 5;
1987
1988            // Parse descriptor
1989            let desc_one = Descriptor::<DescriptorPublicKey>::from_str(raw_desc_one).unwrap();
1990            let desc_two = Descriptor::<DescriptorPublicKey>::from_str(raw_desc_two).unwrap();
1991
1992            // Same string formatting
1993            assert_eq!(desc_one.to_string(), raw_desc_one);
1994            assert_eq!(desc_two.to_string(), raw_desc_two);
1995
1996            // Same address
1997            let addr_one = desc_one
1998                .at_derivation_index(index)
1999                .unwrap()
2000                .derived_descriptor(&secp_ctx)
2001                .unwrap()
2002                .address(&elements::AddressParams::ELEMENTS)
2003                .unwrap();
2004            let addr_two = desc_two
2005                .at_derivation_index(index)
2006                .unwrap()
2007                .derived_descriptor(&secp_ctx)
2008                .unwrap()
2009                .address(&elements::AddressParams::ELEMENTS)
2010                .unwrap();
2011            let addr_expected = elements::Address::from_str(raw_addr_expected).unwrap();
2012            assert_eq!(addr_one, addr_expected);
2013            assert_eq!(addr_two, addr_expected);
2014        }
2015
2016        // P2SH and pubkeys
2017        _test_sortedmulti(
2018            "elsh(sortedmulti(1,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352))#tse3qz98",
2019            "elsh(sortedmulti(1,0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))#ptnf05qc",
2020            "XUDXJZnP2GXsKRKdxSLKzJM1iZ4gbbyrGh",
2021        );
2022
2023        // P2WSH and single-xpub descriptor
2024        _test_sortedmulti(
2025            "elwsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#a8h2v83d",
2026            "elwsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB))#qfcn7ujk",
2027            "ert1qpq2cfgz5lktxzr5zqv7nrzz46hsvq3492ump9pz8rzcl8wqtwqcs2yqnuv",
2028        );
2029
2030        // P2WSH-P2SH and ranged descriptor
2031        _test_sortedmulti(
2032            "elsh(wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*)))#l7qy253t",
2033            "elsh(wsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*)))#0gpee5cl",
2034            "XBkDY63XnRTz6BbwzJi3ifGhBwLTomEzkq",
2035        );
2036    }
2037
2038    #[test]
2039    fn test_parse_descriptor() {
2040        let secp = &secp256k1_zkp::Secp256k1::signing_only();
2041        let (descriptor, key_map) = Descriptor::<_, NoExt>::parse_descriptor(secp, "elwpkh(tprv8ZgxMBicQKsPcwcD4gSnMti126ZiETsuX7qwrtMypr6FBwAP65puFn4v6c3jrN9VwtMRMph6nyT63NrfUL4C3nBzPcduzVSuHD7zbX2JKVc/44'/0'/0'/0/*)").unwrap();
2042        assert_eq!(descriptor.to_string(), "elwpkh([2cbe2a6d/44'/0'/0']tpubDCvNhURocXGZsLNqWcqD3syHTqPXrMSTwi8feKVwAcpi29oYKsDD3Vex7x2TDneKMVN23RbLprfxB69v94iYqdaYHsVz3kPR37NQXeqouVz/0/*)#pznhhta9");
2043        assert_eq!(key_map.len(), 1);
2044
2045        // https://github.com/bitcoin/bitcoin/blob/7ae86b3c6845873ca96650fc69beb4ae5285c801/src/test/descriptor_tests.cpp#L355-L360
2046        macro_rules! check_invalid_checksum {
2047            ($secp: ident,$($desc: expr),*) => {
2048                $(
2049                    match Descriptor::<_, NoExt>::parse_descriptor($secp, $desc) {
2050                        Err(Error::BadDescriptor(_)) => {},
2051                        Err(e) => panic!("Expected bad checksum for {}, got '{}'", $desc, e),
2052                        _ => panic!("Invalid checksum treated as valid: {}", $desc),
2053                    };
2054                )*
2055            };
2056        }
2057        check_invalid_checksum!(secp,
2058            "elsh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#",
2059            "elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#",
2060            "elsh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxf",
2061            "elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5tq",
2062            "elsh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxf",
2063            "elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5",
2064            "elsh(multi(3,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfy",
2065            "elsh(multi(3,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t",
2066            "elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjq09x4t",
2067            "elsh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))##ggssrxfy",
2068            "elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))##tjq09x4t"
2069        );
2070
2071        Descriptor::<_, NoExt>::parse_descriptor(secp, "elsh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#9s2ngs7u").expect("Valid descriptor with checksum");
2072        Descriptor::<_, NoExt>::parse_descriptor(secp, "elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#uklept69").expect("Valid descriptor with checksum");
2073    }
2074
2075    #[test]
2076    #[cfg(feature = "compiler")]
2077    fn parse_and_derive() {
2078        let descriptor_str = "thresh(2,\
2079pk([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*),\
2080pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1),\
2081pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
2082        let policy: policy::concrete::Policy<DescriptorPublicKey> = descriptor_str.parse().unwrap();
2083        let descriptor = Descriptor::<_, NoExt>::new_sh(policy.compile().unwrap()).unwrap();
2084        let definite_descriptor = descriptor.at_derivation_index(42).unwrap();
2085
2086        let res_descriptor_str = "thresh(2,\
2087pk([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/42),\
2088pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1),\
2089pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
2090        let res_policy: policy::concrete::Policy<DescriptorPublicKey> =
2091            res_descriptor_str.parse().unwrap();
2092        let res_descriptor =
2093            Descriptor::<DescriptorPublicKey, NoExt>::new_sh(res_policy.compile().unwrap())
2094                .unwrap();
2095
2096        assert_eq!(res_descriptor.to_string(), definite_descriptor.to_string());
2097    }
2098
2099    #[test]
2100    fn parse_with_secrets() {
2101        let secp = &secp256k1_zkp::Secp256k1::signing_only();
2102        let descriptor_str = "elwpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)#xldrpn5u";
2103        let (descriptor, keymap) =
2104            Descriptor::<DescriptorPublicKey>::parse_descriptor(secp, descriptor_str).unwrap();
2105
2106        let expected = "elwpkh([a12b02f4/44'/0'/0']xpub6BzhLAQUDcBUfHRQHZxDF2AbcJqp4Kaeq6bzJpXrjrWuK26ymTFwkEFbxPra2bJ7yeZKbDjfDeFwxe93JMqpo5SsPJH6dZdvV9kMzJkAZ69/0/*)#20ufqv7z";
2107        assert_eq!(expected, descriptor.to_string());
2108        assert_eq!(keymap.len(), 1);
2109
2110        // try to turn it back into a string with the secrets
2111        assert_eq!(descriptor_str, descriptor.to_string_with_secret(&keymap));
2112    }
2113
2114    #[test]
2115    fn checksum_for_nested_sh() {
2116        let descriptor_str = "elsh(wpkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL))";
2117        let descriptor: Descriptor<DescriptorPublicKey> = descriptor_str.parse().unwrap();
2118        assert_eq!(descriptor.to_string(), "elsh(wpkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL))#2040pn7l");
2119
2120        let descriptor_str = "elsh(wsh(pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))";
2121        let descriptor: Descriptor<DescriptorPublicKey> = descriptor_str.parse().unwrap();
2122        assert_eq!(descriptor.to_string(), "elsh(wsh(pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))#pqs0de7e");
2123    }
2124
2125    #[test]
2126    fn test_xonly_keys() {
2127        let comp_key = "0308c0fcf8895f4361b4fc77afe2ad53b0bd27dcebfd863421b2b246dc283d4103";
2128        let x_only_key = "08c0fcf8895f4361b4fc77afe2ad53b0bd27dcebfd863421b2b246dc283d4103";
2129
2130        // Both x-only keys and comp keys allowed in tr
2131        Descriptor::<DescriptorPublicKey>::from_str(&format!("eltr({})", comp_key)).unwrap();
2132        Descriptor::<DescriptorPublicKey>::from_str(&format!("eltr({})", x_only_key)).unwrap();
2133
2134        // Only compressed keys allowed in wsh
2135        Descriptor::<DescriptorPublicKey>::from_str(&format!("elwsh(pk({}))", comp_key)).unwrap();
2136        Descriptor::<DescriptorPublicKey>::from_str(&format!("elwsh(pk({}))", x_only_key))
2137            .unwrap_err();
2138    }
2139
2140    #[test]
2141    fn test_find_derivation_index_for_spk() {
2142        let secp = secp256k1_zkp::Secp256k1::verification_only();
2143        let descriptor = Descriptor::<_, NoExt>::from_str("eltr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)").unwrap();
2144        let script_at_0_1 = Script::from_hex_no_prefix(
2145            "5120c73ac1b7a518499b9642aed8cfa15d5401e5bd85ad760b937b69521c297722f0",
2146        )
2147        .unwrap();
2148        let expected_concrete = Descriptor::from_str(
2149            "eltr(0283dfe85a3151d2517290da461fe2815591ef69f2b18a2ce63f01697a8b313145)",
2150        )
2151        .unwrap();
2152
2153        assert_eq!(
2154            descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..1),
2155            Ok(None)
2156        );
2157        assert_eq!(
2158            descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..2),
2159            Ok(Some((1, expected_concrete.clone())))
2160        );
2161        assert_eq!(
2162            descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..10),
2163            Ok(Some((1, expected_concrete)))
2164        );
2165    }
2166
2167    #[test]
2168    fn display_alternate() {
2169        let bare = StdDescriptor::from_str(
2170            "elpk(020000000000000000000000000000000000000000000000000000000000000002)",
2171        )
2172        .unwrap();
2173        assert_eq!(
2174            format!("{}", bare),
2175            "elpk(020000000000000000000000000000000000000000000000000000000000000002)#vlpqwfjv",
2176        );
2177        assert_eq!(
2178            format!("{:#}", bare),
2179            "elpk(020000000000000000000000000000000000000000000000000000000000000002)",
2180        );
2181
2182        let pkh = StdDescriptor::from_str(
2183            "elpkh(020000000000000000000000000000000000000000000000000000000000000002)",
2184        )
2185        .unwrap();
2186        assert_eq!(
2187            format!("{}", pkh),
2188            "elpkh(020000000000000000000000000000000000000000000000000000000000000002)#jzq8e832",
2189        );
2190        assert_eq!(
2191            format!("{:#}", pkh),
2192            "elpkh(020000000000000000000000000000000000000000000000000000000000000002)",
2193        );
2194
2195        let wpkh = StdDescriptor::from_str(
2196            "elwpkh(020000000000000000000000000000000000000000000000000000000000000002)",
2197        )
2198        .unwrap();
2199        assert_eq!(
2200            format!("{}", wpkh),
2201            "elwpkh(020000000000000000000000000000000000000000000000000000000000000002)#vxhqdpz9",
2202        );
2203        assert_eq!(
2204            format!("{:#}", wpkh),
2205            "elwpkh(020000000000000000000000000000000000000000000000000000000000000002)",
2206        );
2207
2208        let shwpkh = StdDescriptor::from_str(
2209            "elsh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))",
2210        )
2211        .unwrap();
2212        assert_eq!(
2213            format!("{}", shwpkh),
2214            "elsh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))#h9ajn2ft",
2215        );
2216        assert_eq!(
2217            format!("{:#}", shwpkh),
2218            "elsh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))",
2219        );
2220
2221        let wsh = StdDescriptor::from_str("elwsh(1)").unwrap();
2222        assert_eq!(format!("{}", wsh), "elwsh(1)#s78w5gmj");
2223        assert_eq!(format!("{:#}", wsh), "elwsh(1)");
2224
2225        let sh = StdDescriptor::from_str("elsh(1)").unwrap();
2226        assert_eq!(format!("{}", sh), "elsh(1)#k4aqrx5p");
2227        assert_eq!(format!("{:#}", sh), "elsh(1)");
2228
2229        let shwsh = StdDescriptor::from_str("elsh(wsh(1))").unwrap();
2230        assert_eq!(format!("{}", shwsh), "elsh(wsh(1))#d05z4wjl");
2231        assert_eq!(format!("{:#}", shwsh), "elsh(wsh(1))");
2232
2233        let tr = StdDescriptor::from_str(
2234            "eltr(020000000000000000000000000000000000000000000000000000000000000002)",
2235        )
2236        .unwrap();
2237        assert_eq!(
2238            format!("{}", tr),
2239            "eltr(020000000000000000000000000000000000000000000000000000000000000002)#e874qu8z",
2240        );
2241        assert_eq!(
2242            format!("{:#}", tr),
2243            "eltr(020000000000000000000000000000000000000000000000000000000000000002)",
2244        );
2245    }
2246
2247    #[test]
2248    fn test_regression_29() {
2249        let _ = Descriptor::<String>::from_str("eltr(,thresh(1,spk_eq(,00)))");
2250    }
2251
2252    #[test]
2253    fn multipath_descriptors() {
2254        // We can parse a multipath descriptors, and make it into separate single-path descriptors.
2255        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();
2256        assert!(desc.is_multipath());
2257        assert!(!desc.multipath_length_mismatch());
2258        assert_eq!(desc.into_single_descriptors().unwrap(), vec![
2259            Descriptor::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/7'/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/0/*)))").unwrap(),
2260            Descriptor::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/8h/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/1/*)))").unwrap(),
2261            Descriptor::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/20/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/987/*)))").unwrap()
2262        ]);
2263
2264        // Even if only one of the keys is multipath.
2265        let desc = Descriptor::<DescriptorPublicKey, NoExt>::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap();
2266        assert!(desc.is_multipath());
2267        assert!(!desc.multipath_length_mismatch());
2268        assert_eq!(desc.into_single_descriptors().unwrap(), vec![
2269            Descriptor::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/0/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap(),
2270            Descriptor::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/1/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap(),
2271        ]);
2272
2273        // We can detect regular single-path descriptors.
2274        let notmulti_desc = Descriptor::<DescriptorPublicKey, NoExt>::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap();
2275        assert!(!notmulti_desc.is_multipath());
2276        assert!(!notmulti_desc.multipath_length_mismatch());
2277        assert_eq!(
2278            notmulti_desc.clone().into_single_descriptors().unwrap(),
2279            vec![notmulti_desc]
2280        );
2281
2282        // We refuse to parse multipath descriptors with a mismatch in the number of derivation paths between keys.
2283        Descriptor::<DescriptorPublicKey>::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/<0;1;2;3;4>/*)))").unwrap_err();
2284        Descriptor::<DescriptorPublicKey>::from_str("elwsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1;2;3>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/<0;1;2>/*)))").unwrap_err();
2285    }
2286}