1use core::fmt;
15use core::ops::Range;
16use core::str::{self, FromStr};
17
18use bitcoin::hashes::{hash160, ripemd160, sha256};
19use bitcoin::{
20 secp256k1, Address, Network, Script, ScriptBuf, TxIn, Weight, Witness, WitnessVersion,
21};
22use sync::Arc;
23
24use crate::expression::FromTree as _;
25use crate::miniscript::decode::Terminal;
26use crate::miniscript::limits::MAX_PUBKEYS_PER_MULTISIG;
27use crate::miniscript::{satisfy, Legacy, Miniscript, Segwitv0};
28use crate::plan::{AssetProvider, Plan};
29use crate::prelude::*;
30use crate::{
31 expression, hash256, BareCtx, Error, ForEachKey, FromStrKey, MiniscriptKey, ParseError,
32 Satisfier, Threshold, ToPublicKey, TranslateErr, Translator,
33};
34
35mod bare;
36mod iter;
37mod segwitv0;
38mod sh;
39mod sortedmulti;
40mod tr;
41
42pub use self::bare::{Bare, Pkh};
44pub use self::iter::PkIter;
45pub use self::segwitv0::{Wpkh, Wsh, WshInner};
46pub use self::sh::{Sh, ShInner};
47pub use self::sortedmulti::SortedMultiVec;
48pub use self::tr::{
49 TapTree, TapTreeDepthError, TapTreeIter, TapTreeIterItem, Tr, TrSpendInfo, TrSpendInfoIter,
50 TrSpendInfoIterItem,
51};
52
53pub mod checksum;
54mod key;
55mod key_map;
56
57pub use self::key::{
58 DefiniteDescriptorKey, DerivPaths, DescriptorKeyParseError, DescriptorMultiXKey,
59 DescriptorPublicKey, DescriptorSecretKey, DescriptorXKey, InnerXKey, MalformedKeyDataKind,
60 NonDefiniteKeyError, SinglePriv, SinglePub, SinglePubKey, Wildcard, XKeyNetwork,
61};
62pub use self::key_map::KeyMap;
63
64#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
66pub enum Descriptor<Pk: MiniscriptKey> {
67 Bare(Bare<Pk>),
69 Pkh(Pkh<Pk>),
71 Wpkh(Wpkh<Pk>),
73 Sh(Sh<Pk>),
75 Wsh(Wsh<Pk>),
77 Tr(Tr<Pk>),
79}
80
81impl<Pk: MiniscriptKey> From<Bare<Pk>> for Descriptor<Pk> {
82 #[inline]
83 fn from(inner: Bare<Pk>) -> Self { Descriptor::Bare(inner) }
84}
85
86impl<Pk: MiniscriptKey> From<Pkh<Pk>> for Descriptor<Pk> {
87 #[inline]
88 fn from(inner: Pkh<Pk>) -> Self { Descriptor::Pkh(inner) }
89}
90
91impl<Pk: MiniscriptKey> From<Wpkh<Pk>> for Descriptor<Pk> {
92 #[inline]
93 fn from(inner: Wpkh<Pk>) -> Self { Descriptor::Wpkh(inner) }
94}
95
96impl<Pk: MiniscriptKey> From<Sh<Pk>> for Descriptor<Pk> {
97 #[inline]
98 fn from(inner: Sh<Pk>) -> Self { Descriptor::Sh(inner) }
99}
100
101impl<Pk: MiniscriptKey> From<Wsh<Pk>> for Descriptor<Pk> {
102 #[inline]
103 fn from(inner: Wsh<Pk>) -> Self { Descriptor::Wsh(inner) }
104}
105
106impl<Pk: MiniscriptKey> From<Tr<Pk>> for Descriptor<Pk> {
107 #[inline]
108 fn from(inner: Tr<Pk>) -> Self { Descriptor::Tr(inner) }
109}
110
111#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
113pub enum DescriptorType {
114 Bare,
116 Sh,
118 Pkh,
120 Wpkh,
122 Wsh,
124 ShWsh,
126 ShWpkh,
128 ShSortedMulti,
130 WshSortedMulti,
132 ShWshSortedMulti,
134 Tr,
136}
137
138impl DescriptorType {
139 pub fn segwit_version(&self) -> Option<WitnessVersion> {
143 use self::DescriptorType::*;
144 match self {
145 Tr => Some(WitnessVersion::V1),
146 Wpkh | ShWpkh | Wsh | ShWsh | ShWshSortedMulti | WshSortedMulti => {
147 Some(WitnessVersion::V0)
148 }
149 Bare | Sh | Pkh | ShSortedMulti => None,
150 }
151 }
152}
153
154impl<Pk: MiniscriptKey> Descriptor<Pk> {
155 pub fn new_pk(pk: Pk) -> Self {
159 let ms: Miniscript<Pk, BareCtx> = Miniscript::from_ast(Terminal::Check(Arc::new(
161 Miniscript::from_ast(Terminal::PkK(pk)).expect("Type check cannot fail"),
162 )))
163 .expect("Type check cannot fail");
164 Descriptor::Bare(Bare::new(ms).expect("Context checks cannot fail for p2pk"))
165 }
166
167 pub fn new_pkh(pk: Pk) -> Result<Self, Error> { Ok(Descriptor::Pkh(Pkh::new(pk)?)) }
169
170 pub fn new_wpkh(pk: Pk) -> Result<Self, Error> { Ok(Descriptor::Wpkh(Wpkh::new(pk)?)) }
173
174 pub fn new_sh_wpkh(pk: Pk) -> Result<Self, Error> { Ok(Descriptor::Sh(Sh::new_wpkh(pk)?)) }
177
178 pub fn new_sh(ms: Miniscript<Pk, Legacy>) -> Result<Self, Error> {
184 Ok(Descriptor::Sh(Sh::new(ms)?))
185 }
186
187 pub fn new_wsh(ms: Miniscript<Pk, Segwitv0>) -> Result<Self, Error> {
191 Ok(Descriptor::Wsh(Wsh::new(ms)?))
192 }
193
194 pub fn new_sh_wsh(ms: Miniscript<Pk, Segwitv0>) -> Result<Self, Error> {
198 Ok(Descriptor::Sh(Sh::new_wsh(ms)?))
199 }
200
201 pub fn new_bare(ms: Miniscript<Pk, BareCtx>) -> Result<Self, Error> {
205 Ok(Descriptor::Bare(Bare::new(ms)?))
206 }
207
208 pub fn new_sh_with_wpkh(wpkh: Wpkh<Pk>) -> Self { Descriptor::Sh(Sh::new_with_wpkh(wpkh)) }
212
213 pub fn new_sh_with_wsh(wsh: Wsh<Pk>) -> Self { Descriptor::Sh(Sh::new_with_wsh(wsh)) }
215
216 pub fn new_sh_sortedmulti(
222 thresh: Threshold<Pk, MAX_PUBKEYS_PER_MULTISIG>,
223 ) -> Result<Self, Error> {
224 Ok(Descriptor::Sh(Sh::new_sortedmulti(thresh)?))
225 }
226
227 pub fn new_sh_wsh_sortedmulti(
231 thresh: Threshold<Pk, MAX_PUBKEYS_PER_MULTISIG>,
232 ) -> Result<Self, Error> {
233 Ok(Descriptor::Sh(Sh::new_wsh_sortedmulti(thresh)?))
234 }
235
236 pub fn new_wsh_sortedmulti(
239 thresh: Threshold<Pk, MAX_PUBKEYS_PER_MULTISIG>,
240 ) -> Result<Self, Error> {
241 Ok(Descriptor::Wsh(Wsh::new_sortedmulti(thresh)?))
242 }
243
244 pub fn new_tr(key: Pk, script: Option<tr::TapTree<Pk>>) -> Result<Self, Error> {
247 Ok(Descriptor::Tr(Tr::new(key, script)?))
248 }
249
250 pub fn iter_pk(&self) -> PkIter<'_, Pk> {
252 match *self {
253 Descriptor::Bare(ref bare) => PkIter::from_miniscript_bare(bare.as_inner()),
254 Descriptor::Pkh(ref pk) => PkIter::from_key(pk.as_inner().clone()),
255 Descriptor::Wpkh(ref pk) => PkIter::from_key(pk.as_inner().clone()),
256 Descriptor::Sh(ref sh) => match *sh.as_inner() {
257 ShInner::Wsh(ref wsh) => match wsh.as_inner() {
258 WshInner::SortedMulti(ref sorted) => PkIter::from_sortedmulti(sorted.pks()),
259 WshInner::Ms(ref ms) => PkIter::from_miniscript_segwit(ms),
260 },
261 ShInner::Wpkh(ref pk) => PkIter::from_key(pk.as_inner().clone()),
262 ShInner::SortedMulti(ref sorted) => PkIter::from_sortedmulti(sorted.pks()),
263 ShInner::Ms(ref ms) => PkIter::from_miniscript_legacy(ms),
264 },
265 Descriptor::Wsh(ref wsh) => match wsh.as_inner() {
266 WshInner::SortedMulti(ref sorted) => PkIter::from_sortedmulti(sorted.pks()),
267 WshInner::Ms(ref ms) => PkIter::from_miniscript_segwit(ms),
268 },
269 Descriptor::Tr(ref tr) => PkIter::from_tr(tr),
270 }
271 }
272
273 pub fn internal_key(&self) -> Option<&Pk> {
275 if let Descriptor::Tr(ref tr) = self {
276 Some(tr.internal_key())
277 } else {
278 None
279 }
280 }
281
282 pub fn tap_tree(&self) -> Option<&TapTree<Pk>> {
287 if let Descriptor::Tr(ref tr) = self {
288 tr.tap_tree()
289 } else {
290 None
291 }
292 }
293
294 pub fn tap_tree_iter(&self) -> tr::TapTreeIter<'_, Pk> {
299 if let Descriptor::Tr(ref tr) = self {
300 if let Some(tree) = tr.tap_tree() {
301 return tree.leaves();
302 }
303 }
304 tr::TapTreeIter::empty()
305 }
306
307 pub fn desc_type(&self) -> DescriptorType {
309 match *self {
310 Descriptor::Bare(ref _bare) => DescriptorType::Bare,
311 Descriptor::Pkh(ref _pkh) => DescriptorType::Pkh,
312 Descriptor::Wpkh(ref _wpkh) => DescriptorType::Wpkh,
313 Descriptor::Sh(ref sh) => match sh.as_inner() {
314 ShInner::Wsh(ref wsh) => match wsh.as_inner() {
315 WshInner::SortedMulti(ref _smv) => DescriptorType::ShWshSortedMulti,
316 WshInner::Ms(ref _ms) => DescriptorType::ShWsh,
317 },
318 ShInner::Wpkh(ref _wpkh) => DescriptorType::ShWpkh,
319 ShInner::SortedMulti(ref _smv) => DescriptorType::ShSortedMulti,
320 ShInner::Ms(ref _ms) => DescriptorType::Sh,
321 },
322 Descriptor::Wsh(ref wsh) => match wsh.as_inner() {
323 WshInner::SortedMulti(ref _smv) => DescriptorType::WshSortedMulti,
324 WshInner::Ms(ref _ms) => DescriptorType::Wsh,
325 },
326 Descriptor::Tr(ref _tr) => DescriptorType::Tr,
327 }
328 }
329
330 pub fn sanity_check(&self) -> Result<(), Error> {
340 match *self {
341 Descriptor::Bare(ref bare) => bare.sanity_check(),
342 Descriptor::Pkh(_) => Ok(()),
343 Descriptor::Wpkh(ref wpkh) => wpkh.sanity_check(),
344 Descriptor::Wsh(ref wsh) => wsh.sanity_check(),
345 Descriptor::Sh(ref sh) => sh.sanity_check(),
346 Descriptor::Tr(ref tr) => tr.sanity_check(),
347 }
348 }
349
350 pub fn max_weight_to_satisfy(&self) -> Result<Weight, Error> {
389 let weight = match *self {
390 Descriptor::Bare(ref bare) => bare.max_weight_to_satisfy()?,
391 Descriptor::Pkh(ref pkh) => pkh.max_weight_to_satisfy(),
392 Descriptor::Wpkh(ref wpkh) => wpkh.max_weight_to_satisfy(),
393 Descriptor::Wsh(ref wsh) => wsh.max_weight_to_satisfy()?,
394 Descriptor::Sh(ref sh) => sh.max_weight_to_satisfy()?,
395 Descriptor::Tr(ref tr) => tr.max_weight_to_satisfy()?,
396 };
397 Ok(weight)
398 }
399
400 #[deprecated(
410 since = "10.0.0",
411 note = "Use max_weight_to_satisfy instead. The method to count bytes was redesigned and the results will differ from max_weight_to_satisfy. For more details check rust-bitcoin/rust-miniscript#476."
412 )]
413 #[allow(deprecated)]
414 pub fn max_satisfaction_weight(&self) -> Result<usize, Error> {
415 let weight = match *self {
416 Descriptor::Bare(ref bare) => bare.max_satisfaction_weight()?,
417 Descriptor::Pkh(ref pkh) => pkh.max_satisfaction_weight(),
418 Descriptor::Wpkh(ref wpkh) => wpkh.max_satisfaction_weight(),
419 Descriptor::Wsh(ref wsh) => wsh.max_satisfaction_weight()?,
420 Descriptor::Sh(ref sh) => sh.max_satisfaction_weight()?,
421 Descriptor::Tr(ref tr) => tr.max_satisfaction_weight()?,
422 };
423 Ok(weight)
424 }
425
426 pub fn translate_pk<T>(
428 &self,
429 t: &mut T,
430 ) -> Result<Descriptor<T::TargetPk>, TranslateErr<T::Error>>
431 where
432 T: Translator<Pk>,
433 {
434 let desc = match *self {
435 Descriptor::Bare(ref bare) => Descriptor::Bare(bare.translate_pk(t)?),
436 Descriptor::Pkh(ref pk) => Descriptor::Pkh(pk.translate_pk(t)?),
437 Descriptor::Wpkh(ref pk) => Descriptor::Wpkh(pk.translate_pk(t)?),
438 Descriptor::Sh(ref sh) => Descriptor::Sh(sh.translate_pk(t)?),
439 Descriptor::Wsh(ref wsh) => Descriptor::Wsh(wsh.translate_pk(t)?),
440 Descriptor::Tr(ref tr) => Descriptor::Tr(tr.translate_pk(t)?),
441 };
442 Ok(desc)
443 }
444}
445
446impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
447 pub fn address(&self, network: Network) -> Result<Address, Error> {
454 match *self {
455 Descriptor::Bare(_) => Err(Error::BareDescriptorAddr),
456 Descriptor::Pkh(ref pkh) => Ok(pkh.address(network)),
457 Descriptor::Wpkh(ref wpkh) => Ok(wpkh.address(network)),
458 Descriptor::Wsh(ref wsh) => Ok(wsh.address(network)),
459 Descriptor::Sh(ref sh) => Ok(sh.address(network)),
460 Descriptor::Tr(ref tr) => Ok(tr.address(network)),
461 }
462 }
463
464 pub fn script_pubkey(&self) -> ScriptBuf {
466 match *self {
467 Descriptor::Bare(ref bare) => bare.script_pubkey(),
468 Descriptor::Pkh(ref pkh) => pkh.script_pubkey(),
469 Descriptor::Wpkh(ref wpkh) => wpkh.script_pubkey(),
470 Descriptor::Wsh(ref wsh) => wsh.script_pubkey(),
471 Descriptor::Sh(ref sh) => sh.script_pubkey(),
472 Descriptor::Tr(ref tr) => tr.script_pubkey(),
473 }
474 }
475
476 pub fn unsigned_script_sig(&self) -> ScriptBuf {
484 match *self {
485 Descriptor::Bare(_) => ScriptBuf::new(),
486 Descriptor::Pkh(_) => ScriptBuf::new(),
487 Descriptor::Wpkh(_) => ScriptBuf::new(),
488 Descriptor::Wsh(_) => ScriptBuf::new(),
489 Descriptor::Sh(ref sh) => sh.unsigned_script_sig(),
490 Descriptor::Tr(_) => ScriptBuf::new(),
491 }
492 }
493
494 pub fn explicit_script(&self) -> Result<ScriptBuf, Error> {
501 match *self {
502 Descriptor::Bare(ref bare) => Ok(bare.script_pubkey()),
503 Descriptor::Pkh(ref pkh) => Ok(pkh.script_pubkey()),
504 Descriptor::Wpkh(ref wpkh) => Ok(wpkh.script_pubkey()),
505 Descriptor::Wsh(ref wsh) => Ok(wsh.inner_script()),
506 Descriptor::Sh(ref sh) => Ok(sh.inner_script()),
507 Descriptor::Tr(_) => Err(Error::TrNoScriptCode),
508 }
509 }
510
511 pub fn script_code(&self) -> Result<ScriptBuf, Error> {
519 match *self {
520 Descriptor::Bare(ref bare) => Ok(bare.ecdsa_sighash_script_code()),
521 Descriptor::Pkh(ref pkh) => Ok(pkh.ecdsa_sighash_script_code()),
522 Descriptor::Wpkh(ref wpkh) => Ok(wpkh.ecdsa_sighash_script_code()),
523 Descriptor::Wsh(ref wsh) => Ok(wsh.ecdsa_sighash_script_code()),
524 Descriptor::Sh(ref sh) => Ok(sh.ecdsa_sighash_script_code()),
525 Descriptor::Tr(_) => Err(Error::TrNoScriptCode),
526 }
527 }
528
529 pub fn get_satisfaction<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, ScriptBuf), Error>
533 where
534 S: Satisfier<Pk>,
535 {
536 match *self {
537 Descriptor::Bare(ref bare) => bare.get_satisfaction(satisfier),
538 Descriptor::Pkh(ref pkh) => pkh.get_satisfaction(satisfier),
539 Descriptor::Wpkh(ref wpkh) => wpkh.get_satisfaction(satisfier),
540 Descriptor::Wsh(ref wsh) => wsh.get_satisfaction(satisfier),
541 Descriptor::Sh(ref sh) => sh.get_satisfaction(satisfier),
542 Descriptor::Tr(ref tr) => tr.get_satisfaction(&satisfier),
543 }
544 }
545
546 pub fn get_satisfaction_mall<S>(&self, satisfier: S) -> Result<(Vec<Vec<u8>>, ScriptBuf), Error>
550 where
551 S: Satisfier<Pk>,
552 {
553 match *self {
554 Descriptor::Bare(ref bare) => bare.get_satisfaction_mall(satisfier),
555 Descriptor::Pkh(ref pkh) => pkh.get_satisfaction_mall(satisfier),
556 Descriptor::Wpkh(ref wpkh) => wpkh.get_satisfaction_mall(satisfier),
557 Descriptor::Wsh(ref wsh) => wsh.get_satisfaction_mall(satisfier),
558 Descriptor::Sh(ref sh) => sh.get_satisfaction_mall(satisfier),
559 Descriptor::Tr(ref tr) => tr.get_satisfaction_mall(&satisfier),
560 }
561 }
562
563 pub fn satisfy<S>(&self, txin: &mut TxIn, satisfier: S) -> Result<(), Error>
567 where
568 S: Satisfier<Pk>,
569 {
570 let (witness, script_sig) = self.get_satisfaction(satisfier)?;
571 txin.witness = Witness::from_slice(&witness);
572 txin.script_sig = script_sig;
573 Ok(())
574 }
575}
576
577impl Descriptor<DefiniteDescriptorKey> {
578 #[allow(clippy::result_large_err)] pub fn plan<P>(self, provider: &P) -> Result<Plan, Self>
583 where
584 P: AssetProvider<DefiniteDescriptorKey>,
585 {
586 let satisfaction = match self {
587 Descriptor::Bare(ref bare) => bare.plan_satisfaction(provider),
588 Descriptor::Pkh(ref pkh) => pkh.plan_satisfaction(provider),
589 Descriptor::Wpkh(ref wpkh) => wpkh.plan_satisfaction(provider),
590 Descriptor::Wsh(ref wsh) => wsh.plan_satisfaction(provider),
591 Descriptor::Sh(ref sh) => sh.plan_satisfaction(provider),
592 Descriptor::Tr(ref tr) => tr.plan_satisfaction(provider),
593 };
594
595 if let satisfy::Witness::Stack(stack) = satisfaction.stack {
596 Ok(Plan {
597 descriptor: self,
598 template: stack,
599 absolute_timelock: satisfaction.absolute_timelock.map(Into::into),
600 relative_timelock: satisfaction.relative_timelock.map(Into::into),
601 })
602 } else {
603 Err(self)
604 }
605 }
606
607 #[allow(clippy::result_large_err)] pub fn plan_mall<P>(self, provider: &P) -> Result<Plan, Self>
612 where
613 P: AssetProvider<DefiniteDescriptorKey>,
614 {
615 let satisfaction = match self {
616 Descriptor::Bare(ref bare) => bare.plan_satisfaction_mall(provider),
617 Descriptor::Pkh(ref pkh) => pkh.plan_satisfaction_mall(provider),
618 Descriptor::Wpkh(ref wpkh) => wpkh.plan_satisfaction_mall(provider),
619 Descriptor::Wsh(ref wsh) => wsh.plan_satisfaction_mall(provider),
620 Descriptor::Sh(ref sh) => sh.plan_satisfaction_mall(provider),
621 Descriptor::Tr(ref tr) => tr.plan_satisfaction_mall(provider),
622 };
623
624 if let satisfy::Witness::Stack(stack) = satisfaction.stack {
625 Ok(Plan {
626 descriptor: self,
627 template: stack,
628 absolute_timelock: satisfaction.absolute_timelock.map(Into::into),
629 relative_timelock: satisfaction.relative_timelock.map(Into::into),
631 })
632 } else {
633 Err(self)
634 }
635 }
636}
637
638impl<Pk: MiniscriptKey> ForEachKey<Pk> for Descriptor<Pk> {
639 fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
640 match *self {
641 Descriptor::Bare(ref bare) => bare.for_each_key(pred),
642 Descriptor::Pkh(ref pkh) => pkh.for_each_key(pred),
643 Descriptor::Wpkh(ref wpkh) => wpkh.for_each_key(pred),
644 Descriptor::Wsh(ref wsh) => wsh.for_each_key(pred),
645 Descriptor::Sh(ref sh) => sh.for_each_key(pred),
646 Descriptor::Tr(ref tr) => tr.for_each_key(pred),
647 }
648 }
649}
650
651impl Descriptor<DescriptorPublicKey> {
652 pub fn has_wildcard(&self) -> bool { self.for_any_key(|key| key.has_wildcard()) }
654
655 pub fn at_derivation_index(
662 &self,
663 index: u32,
664 ) -> Result<Descriptor<DefiniteDescriptorKey>, NonDefiniteKeyError> {
665 struct Derivator(u32);
666
667 impl Translator<DescriptorPublicKey> for Derivator {
668 type TargetPk = DefiniteDescriptorKey;
669 type Error = NonDefiniteKeyError;
670
671 fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<Self::TargetPk, Self::Error> {
672 pk.clone().at_derivation_index(self.0)
673 }
674
675 translate_hash_clone!(DescriptorPublicKey);
676 }
677 self.translate_pk(&mut Derivator(index))
678 .map_err(|e| e.expect_translator_err("No Context errors while translating"))
679 }
680
681 pub fn derived_descriptor<C: secp256k1::Verification>(
709 &self,
710 secp: &secp256k1::Secp256k1<C>,
711 index: u32,
712 ) -> Result<Descriptor<bitcoin::PublicKey>, NonDefiniteKeyError> {
713 Ok(self.at_derivation_index(index)?.derived_descriptor(secp))
714 }
715
716 pub fn parse_descriptor<C: secp256k1::Signing>(
721 secp: &secp256k1::Secp256k1<C>,
722 s: &str,
723 ) -> Result<(Descriptor<DescriptorPublicKey>, KeyMap), Error> {
724 fn parse_key<C: secp256k1::Signing>(
725 s: &str,
726 key_map: &mut KeyMap,
727 secp: &secp256k1::Secp256k1<C>,
728 ) -> Result<DescriptorPublicKey, Error> {
729 match DescriptorSecretKey::from_str(s) {
730 Ok(sk) => {
731 let pk = key_map
732 .insert(secp, sk)
733 .map_err(|e| Error::Unexpected(e.to_string()))?;
734 Ok(pk)
735 }
736 Err(_) => {
737 let pk = s
739 .parse()
740 .map_err(|e| Error::Parse(ParseError::box_from_str(e)))?;
741 Ok(pk)
742 }
743 }
744 }
745
746 let mut keymap_pk = KeyMapWrapper(KeyMap::new(), secp);
747
748 struct KeyMapWrapper<'a, C: secp256k1::Signing>(KeyMap, &'a secp256k1::Secp256k1<C>);
749
750 impl<C: secp256k1::Signing> Translator<String> for KeyMapWrapper<'_, C> {
751 type TargetPk = DescriptorPublicKey;
752 type Error = Error;
753
754 fn pk(&mut self, pk: &String) -> Result<DescriptorPublicKey, Error> {
755 parse_key(pk, &mut self.0, self.1)
756 }
757
758 fn sha256(&mut self, sha256: &String) -> Result<sha256::Hash, Error> {
759 sha256
760 .parse()
761 .map_err(|e| Error::Parse(ParseError::box_from_str(e)))
762 }
763
764 fn hash256(&mut self, hash256: &String) -> Result<hash256::Hash, Error> {
765 hash256
766 .parse()
767 .map_err(|e| Error::Parse(ParseError::box_from_str(e)))
768 }
769
770 fn ripemd160(&mut self, ripemd160: &String) -> Result<ripemd160::Hash, Error> {
771 ripemd160
772 .parse()
773 .map_err(|e| Error::Parse(ParseError::box_from_str(e)))
774 }
775
776 fn hash160(&mut self, hash160: &String) -> Result<hash160::Hash, Error> {
777 hash160
778 .parse()
779 .map_err(|e| Error::Parse(ParseError::box_from_str(e)))
780 }
781 }
782
783 let descriptor = Descriptor::<String>::from_str(s)?;
784 let descriptor = descriptor
785 .translate_pk(&mut keymap_pk)
786 .map_err(TranslateErr::flatten)?;
787
788 Ok((descriptor, keymap_pk.0))
789 }
790
791 pub fn to_string_with_secret(&self, key_map: &KeyMap) -> String {
793 struct KeyMapLookUp<'a>(&'a KeyMap);
794
795 impl Translator<DescriptorPublicKey> for KeyMapLookUp<'_> {
796 type TargetPk = String;
797 type Error = core::convert::Infallible;
798
799 fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<String, Self::Error> {
800 key_to_string(pk, self.0)
801 }
802
803 fn sha256(&mut self, sha256: &sha256::Hash) -> Result<String, Self::Error> {
804 Ok(sha256.to_string())
805 }
806
807 fn hash256(&mut self, hash256: &hash256::Hash) -> Result<String, Self::Error> {
808 Ok(hash256.to_string())
809 }
810
811 fn ripemd160(&mut self, ripemd160: &ripemd160::Hash) -> Result<String, Self::Error> {
812 Ok(ripemd160.to_string())
813 }
814
815 fn hash160(&mut self, hash160: &hash160::Hash) -> Result<String, Self::Error> {
816 Ok(hash160.to_string())
817 }
818 }
819
820 fn key_to_string(
821 pk: &DescriptorPublicKey,
822 key_map: &KeyMap,
823 ) -> Result<String, core::convert::Infallible> {
824 Ok(match key_map.get(pk) {
825 Some(secret) => secret.to_string(),
826 None => pk.to_string(),
827 })
828 }
829
830 let descriptor = self
831 .translate_pk(&mut KeyMapLookUp(key_map))
832 .expect("Translation to string cannot fail");
833
834 descriptor.to_string()
835 }
836
837 pub fn find_derivation_index_for_spk<C: secp256k1::Verification>(
845 &self,
846 secp: &secp256k1::Secp256k1<C>,
847 script_pubkey: &Script,
848 range: Range<u32>,
849 ) -> Result<Option<(u32, Descriptor<bitcoin::PublicKey>)>, NonDefiniteKeyError> {
850 let range = if self.has_wildcard() { range } else { 0..1 };
851
852 for i in range {
853 let concrete = self.derived_descriptor(secp, i)?;
854 if &concrete.script_pubkey() == script_pubkey {
855 return Ok(Some((i, concrete)));
856 }
857 }
858
859 Ok(None)
860 }
861
862 pub fn is_multipath(&self) -> bool { self.for_any_key(DescriptorPublicKey::is_multipath) }
864
865 #[allow(clippy::blocks_in_conditions)]
870 pub fn into_single_descriptors(self) -> Result<Vec<Descriptor<DescriptorPublicKey>>, Error> {
871 let mut descriptors = Vec::new();
873 if !self.for_any_key(|key| {
875 if !descriptors.is_empty() {
878 return true;
879 }
880
881 match key {
882 DescriptorPublicKey::Single(..) | DescriptorPublicKey::XPub(..) => false,
883 DescriptorPublicKey::MultiXPub(xpub) => {
884 for _ in 0..xpub.derivation_paths.paths().len() {
885 descriptors.push(self.clone());
886 }
887 true
888 }
889 }
890 }) {
891 return Ok(vec![self]);
893 }
894 assert!(!descriptors.is_empty());
895
896 struct IndexChoser(usize);
898 impl Translator<DescriptorPublicKey> for IndexChoser {
899 type TargetPk = DescriptorPublicKey;
900 type Error = Error;
901
902 fn pk(&mut self, pk: &DescriptorPublicKey) -> Result<DescriptorPublicKey, Error> {
903 match pk {
904 DescriptorPublicKey::Single(..) | DescriptorPublicKey::XPub(..) => {
905 Ok(pk.clone())
906 }
907 DescriptorPublicKey::MultiXPub(_) => pk
908 .clone()
909 .into_single_keys()
910 .get(self.0)
911 .cloned()
912 .ok_or(Error::MultipathDescLenMismatch),
913 }
914 }
915 translate_hash_clone!(DescriptorPublicKey);
916 }
917
918 for (i, desc) in descriptors.iter_mut().enumerate() {
919 let mut index_choser = IndexChoser(i);
920 *desc = desc
921 .translate_pk(&mut index_choser)
922 .map_err(|e| e.expect_translator_err("No Context errors possible"))?;
923 }
924
925 Ok(descriptors)
926 }
927
928 pub fn xkey_network(&self) -> XKeyNetwork {
937 let mut first_network = None;
938
939 for key in self.iter_pk() {
940 if let Some(network) = key.xkey_network() {
941 match first_network {
942 None => first_network = Some(network),
943 Some(ref n) if *n != network => return XKeyNetwork::Mixed,
944 _ => continue,
945 }
946 }
947 }
948
949 match first_network {
950 Some(network) => XKeyNetwork::Single(network),
951 None => XKeyNetwork::NoXKeys,
952 }
953 }
954}
955
956impl Descriptor<DefiniteDescriptorKey> {
957 pub fn derived_descriptor<C: secp256k1::Verification>(
980 &self,
981 secp: &secp256k1::Secp256k1<C>,
982 ) -> Descriptor<bitcoin::PublicKey> {
983 struct Derivator<'a, C: secp256k1::Verification>(&'a secp256k1::Secp256k1<C>);
984
985 impl<C: secp256k1::Verification> Translator<DefiniteDescriptorKey> for Derivator<'_, C> {
986 type TargetPk = bitcoin::PublicKey;
987 type Error = core::convert::Infallible;
988
989 fn pk(&mut self, pk: &DefiniteDescriptorKey) -> Result<Self::TargetPk, Self::Error> {
990 Ok(pk.derive_public_key(self.0))
991 }
992
993 translate_hash_clone!(DefiniteDescriptorKey);
994 }
995
996 let derived = self.translate_pk(&mut Derivator(secp));
997 match derived {
998 Ok(derived) => derived,
999 Err(e) => panic!("Context errors when deriving keys: {}", e.into_outer_err()),
1002 }
1003 }
1004
1005 pub fn xkey_network(&self) -> XKeyNetwork {
1014 let mut first_network = None;
1015
1016 for key in self.iter_pk() {
1017 if let Some(network) = key.as_descriptor_public_key().xkey_network() {
1018 match first_network {
1019 None => first_network = Some(network),
1020 Some(ref n) if *n != network => return XKeyNetwork::Mixed,
1021 _ => continue,
1022 }
1023 }
1024 }
1025
1026 match first_network {
1027 Some(network) => XKeyNetwork::Single(network),
1028 None => XKeyNetwork::NoXKeys,
1029 }
1030 }
1031}
1032
1033impl<Pk: FromStrKey> crate::expression::FromTree for Descriptor<Pk> {
1034 fn from_tree(top: expression::TreeIterItem) -> Result<Descriptor<Pk>, Error> {
1036 Ok(match (top.name(), top.n_children()) {
1037 ("pkh", 1) => Descriptor::Pkh(Pkh::from_tree(top)?),
1038 ("wpkh", 1) => Descriptor::Wpkh(Wpkh::from_tree(top)?),
1039 ("sh", 1) => Descriptor::Sh(Sh::from_tree(top)?),
1040 ("wsh", 1) => Descriptor::Wsh(Wsh::from_tree(top)?),
1041 ("tr", _) => Descriptor::Tr(Tr::from_tree(top)?),
1042 _ => Descriptor::Bare(Bare::from_tree(top)?),
1043 })
1044 }
1045}
1046
1047impl<Pk: FromStrKey> FromStr for Descriptor<Pk> {
1048 type Err = Error;
1049 fn from_str(s: &str) -> Result<Descriptor<Pk>, Error> {
1050 let top = expression::Tree::from_str(s)?;
1051 let ret = Self::from_tree(top.root())?;
1052 if let Descriptor::Tr(ref inner) = ret {
1053 ret.sanity_check()?;
1056 for item in inner.leaves() {
1057 item.miniscript()
1058 .ext_check(&crate::miniscript::analyzable::ExtParams::sane())?;
1059 }
1060 }
1061 Ok(ret)
1062 }
1063}
1064
1065impl<Pk: MiniscriptKey> fmt::Debug for Descriptor<Pk> {
1066 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1067 match *self {
1068 Descriptor::Bare(ref sub) => fmt::Debug::fmt(sub, f),
1069 Descriptor::Pkh(ref pkh) => fmt::Debug::fmt(pkh, f),
1070 Descriptor::Wpkh(ref wpkh) => fmt::Debug::fmt(wpkh, f),
1071 Descriptor::Sh(ref sub) => fmt::Debug::fmt(sub, f),
1072 Descriptor::Wsh(ref sub) => fmt::Debug::fmt(sub, f),
1073 Descriptor::Tr(ref tr) => fmt::Debug::fmt(tr, f),
1074 }
1075 }
1076}
1077
1078impl<Pk: MiniscriptKey> fmt::Display for Descriptor<Pk> {
1079 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1080 match *self {
1081 Descriptor::Bare(ref sub) => fmt::Display::fmt(sub, f),
1082 Descriptor::Pkh(ref pkh) => fmt::Display::fmt(pkh, f),
1083 Descriptor::Wpkh(ref wpkh) => fmt::Display::fmt(wpkh, f),
1084 Descriptor::Sh(ref sub) => fmt::Display::fmt(sub, f),
1085 Descriptor::Wsh(ref sub) => fmt::Display::fmt(sub, f),
1086 Descriptor::Tr(ref tr) => fmt::Display::fmt(tr, f),
1087 }
1088 }
1089}
1090
1091serde_string_impl_pk!(Descriptor, "a script descriptor");
1092
1093macro_rules! write_descriptor {
1094 ($fmt:expr, $s:literal $(, $args:expr)*) => {
1095 {
1096 use fmt::Write as _;
1097
1098 let mut wrapped_f = $crate::descriptor::checksum::Formatter::new($fmt);
1099 write!(wrapped_f, $s $(, $args)*)?;
1100 wrapped_f.write_checksum_if_not_alt()?;
1101
1102 fmt::Result::Ok(())
1103 }
1104 }
1105}
1106pub(crate) use write_descriptor;
1107
1108#[cfg(test)]
1109mod tests {
1110 use core::convert::TryFrom;
1111
1112 use bitcoin::blockdata::opcodes::all::{OP_CLTV, OP_CSV};
1113 use bitcoin::blockdata::script::Instruction;
1114 use bitcoin::blockdata::{opcodes, script};
1115 use bitcoin::hashes::Hash;
1116 use bitcoin::script::PushBytes;
1117 use bitcoin::sighash::EcdsaSighashType;
1118 use bitcoin::{bip32, PublicKey, Sequence, XOnlyPublicKey};
1119
1120 use super::{checksum, *};
1121 use crate::hex_script;
1122 #[cfg(feature = "compiler")]
1123 use crate::policy;
1124
1125 type StdDescriptor = Descriptor<PublicKey>;
1126 const TEST_PK: &str = "pk(020000000000000000000000000000000000000000000000000000000000000002)";
1127
1128 fn roundtrip_descriptor(s: &str) {
1129 let desc = Descriptor::<String>::from_str(s).unwrap();
1130 let output = desc.to_string();
1131 let normalize_aliases = s.replace("c:pk_k(", "pk(").replace("c:pk_h(", "pkh(");
1132
1133 let mut checksum_eng = checksum::Engine::new();
1134 checksum_eng.input(&normalize_aliases).unwrap();
1135 assert_eq!(format!("{}#{}", &normalize_aliases, checksum_eng.checksum()), output);
1136 }
1137
1138 #[test]
1139 fn display_prefers_u() {
1140 let desc = StdDescriptor::from_str("sh(u:0)").unwrap();
1145 assert_eq!("sh(u:0)#ncq3yf9h", desc.to_string());
1146
1147 let desc = StdDescriptor::from_str("sh(and_n(u:0,1))").unwrap();
1150 assert_eq!("sh(and_n(u:0,1))#5j5tw8nm", desc.to_string());
1151 }
1152
1153 #[test]
1154 fn desc_rtt_tests() {
1155 roundtrip_descriptor("c:pk_k()");
1156 roundtrip_descriptor("wsh(pk())");
1157 roundtrip_descriptor("wsh(c:pk_k())");
1158 roundtrip_descriptor("c:pk_h()");
1159 }
1160 #[test]
1161 fn parse_descriptor() {
1162 StdDescriptor::from_str("(").unwrap_err();
1163 StdDescriptor::from_str("(x()").unwrap_err();
1164 StdDescriptor::from_str("(\u{7f}()3").unwrap_err();
1165 StdDescriptor::from_str("pk()").unwrap_err();
1166 StdDescriptor::from_str("nl:0").unwrap_err(); assert_eq!(
1168 StdDescriptor::from_str("sh(sortedmulti)")
1169 .unwrap_err()
1170 .to_string(),
1171 "sortedmulti must have at least 1 children, but found 0"
1172 ); assert_eq!(
1174 StdDescriptor::from_str(&format!("sh(sortedmulti(2,{}))", &TEST_PK[3..69]))
1175 .unwrap_err()
1176 .to_string(),
1177 "invalid threshold 2-of-1; cannot have k > n",
1178 ); StdDescriptor::from_str(TEST_PK).unwrap();
1181
1182 let uncompressed_pk =
1183 "0414fc03b8df87cd7b872996810db8458d61da8448e531569c8517b469a119d267be5645686309c6e6736dbd93940707cc9143d3cf29f1b877ff340e2cb2d259cf";
1184
1185 StdDescriptor::from_str(&format!("pk({})", uncompressed_pk)).unwrap();
1187 StdDescriptor::from_str(&format!("pkh({})", uncompressed_pk)).unwrap();
1188 StdDescriptor::from_str(&format!("sh(pk({}))", uncompressed_pk)).unwrap();
1189 StdDescriptor::from_str(&format!("wpkh({})", uncompressed_pk)).unwrap_err();
1190 StdDescriptor::from_str(&format!("sh(wpkh({}))", uncompressed_pk)).unwrap_err();
1191 StdDescriptor::from_str(&format!("wsh(pk{})", uncompressed_pk)).unwrap_err();
1192 StdDescriptor::from_str(&format!("sh(wsh(pk{}))", uncompressed_pk)).unwrap_err();
1193 StdDescriptor::from_str(&format!("or_i(pk({}),pk({}))", uncompressed_pk, uncompressed_pk))
1194 .unwrap_err();
1195 }
1196
1197 #[test]
1198 pub fn script_pubkey() {
1199 let bare = StdDescriptor::from_str(
1200 "multi(1,020000000000000000000000000000000000000000000000000000000000000002)",
1201 )
1202 .unwrap();
1203 assert_eq!(
1204 bare.script_pubkey(),
1205 hex_script(
1206 "512102000000000000000000000000000000000000000000000000000000000000000251ae"
1207 )
1208 );
1209 assert_eq!(
1210 bare.address(Network::Bitcoin).unwrap_err().to_string(),
1211 "Bare descriptors don't have address"
1212 );
1213
1214 let pk = StdDescriptor::from_str(TEST_PK).unwrap();
1215 assert_eq!(
1216 pk.script_pubkey(),
1217 ScriptBuf::from(vec![
1218 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1220 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xac,
1221 ])
1222 );
1223
1224 let pkh = StdDescriptor::from_str(
1225 "pkh(\
1226 020000000000000000000000000000000000000000000000000000000000000002\
1227 )",
1228 )
1229 .unwrap();
1230 assert_eq!(
1231 pkh.script_pubkey(),
1232 script::Builder::new()
1233 .push_opcode(opcodes::all::OP_DUP)
1234 .push_opcode(opcodes::all::OP_HASH160)
1235 .push_slice(
1236 hash160::Hash::from_str("84e9ed95a38613f0527ff685a9928abe2d4754d4",)
1237 .unwrap()
1238 .to_byte_array()
1239 )
1240 .push_opcode(opcodes::all::OP_EQUALVERIFY)
1241 .push_opcode(opcodes::all::OP_CHECKSIG)
1242 .into_script()
1243 );
1244 assert_eq!(
1245 pkh.address(Network::Bitcoin,).unwrap().to_string(),
1246 "1D7nRvrRgzCg9kYBwhPH3j3Gs6SmsRg3Wq"
1247 );
1248
1249 let wpkh = StdDescriptor::from_str(
1250 "wpkh(\
1251 020000000000000000000000000000000000000000000000000000000000000002\
1252 )",
1253 )
1254 .unwrap();
1255 assert_eq!(
1256 wpkh.script_pubkey(),
1257 script::Builder::new()
1258 .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1259 .push_slice(
1260 hash160::Hash::from_str("84e9ed95a38613f0527ff685a9928abe2d4754d4",)
1261 .unwrap()
1262 .to_byte_array()
1263 )
1264 .into_script()
1265 );
1266 assert_eq!(
1267 wpkh.address(Network::Bitcoin,).unwrap().to_string(),
1268 "bc1qsn57m9drscflq5nl76z6ny52hck5w4x5wqd9yt"
1269 );
1270
1271 let shwpkh = StdDescriptor::from_str(
1272 "sh(wpkh(\
1273 020000000000000000000000000000000000000000000000000000000000000002\
1274 ))",
1275 )
1276 .unwrap();
1277 assert_eq!(
1278 shwpkh.script_pubkey(),
1279 script::Builder::new()
1280 .push_opcode(opcodes::all::OP_HASH160)
1281 .push_slice(
1282 hash160::Hash::from_str("f1c3b9a431134cb90a500ec06e0067cfa9b8bba7",)
1283 .unwrap()
1284 .to_byte_array()
1285 )
1286 .push_opcode(opcodes::all::OP_EQUAL)
1287 .into_script()
1288 );
1289 assert_eq!(
1290 shwpkh.address(Network::Bitcoin,).unwrap().to_string(),
1291 "3PjMEzoveVbvajcnDDuxcJhsuqPHgydQXq"
1292 );
1293
1294 let sh = StdDescriptor::from_str(
1295 "sh(c:pk_k(\
1296 020000000000000000000000000000000000000000000000000000000000000002\
1297 ))",
1298 )
1299 .unwrap();
1300 assert_eq!(
1301 sh.script_pubkey(),
1302 script::Builder::new()
1303 .push_opcode(opcodes::all::OP_HASH160)
1304 .push_slice(
1305 hash160::Hash::from_str("aa5282151694d3f2f32ace7d00ad38f927a33ac8",)
1306 .unwrap()
1307 .to_byte_array()
1308 )
1309 .push_opcode(opcodes::all::OP_EQUAL)
1310 .into_script()
1311 );
1312 assert_eq!(
1313 sh.address(Network::Bitcoin,).unwrap().to_string(),
1314 "3HDbdvM9CQ6ASnQFUkWw6Z4t3qNwMesJE9"
1315 );
1316
1317 let wsh = StdDescriptor::from_str(
1318 "wsh(c:pk_k(\
1319 020000000000000000000000000000000000000000000000000000000000000002\
1320 ))",
1321 )
1322 .unwrap();
1323 assert_eq!(
1324 wsh.script_pubkey(),
1325 script::Builder::new()
1326 .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1327 .push_slice(
1328 sha256::Hash::from_str(
1329 "\
1330 f9379edc8983152dc781747830075bd5\
1331 3896e4b0ce5bff73777fd77d124ba085\
1332 "
1333 )
1334 .unwrap()
1335 .to_byte_array()
1336 )
1337 .into_script()
1338 );
1339 assert_eq!(
1340 wsh.address(Network::Bitcoin,).unwrap().to_string(),
1341 "bc1qlymeahyfsv2jm3upw3urqp6m65ufde9seedl7umh0lth6yjt5zzsk33tv6"
1342 );
1343
1344 let shwsh = StdDescriptor::from_str(
1345 "sh(wsh(c:pk_k(\
1346 020000000000000000000000000000000000000000000000000000000000000002\
1347 )))",
1348 )
1349 .unwrap();
1350 assert_eq!(
1351 shwsh.script_pubkey(),
1352 script::Builder::new()
1353 .push_opcode(opcodes::all::OP_HASH160)
1354 .push_slice(
1355 hash160::Hash::from_str("4bec5d7feeed99e1d0a23fe32a4afe126a7ff07e",)
1356 .unwrap()
1357 .to_byte_array()
1358 )
1359 .push_opcode(opcodes::all::OP_EQUAL)
1360 .into_script()
1361 );
1362 assert_eq!(
1363 shwsh.address(Network::Bitcoin,).unwrap().to_string(),
1364 "38cTksiyPT2b1uGRVbVqHdDhW9vKs84N6Z"
1365 );
1366 }
1367
1368 #[test]
1369 fn satisfy() {
1370 let secp = secp256k1::Secp256k1::new();
1371 let sk =
1372 secp256k1::SecretKey::from_slice(&b"sally was a secret key, she said"[..]).unwrap();
1373 let pk = bitcoin::PublicKey::new(secp256k1::PublicKey::from_secret_key(&secp, &sk));
1374 let msg = secp256k1::Message::from_digest_slice(&b"michael was a message, amusingly"[..])
1375 .expect("32 bytes");
1376 let sig = secp.sign_ecdsa(&msg, &sk);
1377 let mut sigser = sig.serialize_der().to_vec();
1378 sigser.push(0x01); struct SimpleSat {
1381 sig: secp256k1::ecdsa::Signature,
1382 pk: bitcoin::PublicKey,
1383 }
1384
1385 impl Satisfier<bitcoin::PublicKey> for SimpleSat {
1386 fn lookup_ecdsa_sig(
1387 &self,
1388 pk: &bitcoin::PublicKey,
1389 ) -> Option<bitcoin::ecdsa::Signature> {
1390 if *pk == self.pk {
1391 Some(bitcoin::ecdsa::Signature {
1392 signature: self.sig,
1393 sighash_type: bitcoin::sighash::EcdsaSighashType::All,
1394 })
1395 } else {
1396 None
1397 }
1398 }
1399 }
1400
1401 let satisfier = SimpleSat { sig, pk };
1402 let ms = ms_str!("c:pk_k({})", pk);
1403
1404 let mut txin = bitcoin::TxIn {
1405 previous_output: bitcoin::OutPoint::default(),
1406 script_sig: bitcoin::ScriptBuf::new(),
1407 sequence: Sequence::from_height(100),
1408 witness: Witness::default(),
1409 };
1410 let bare = Descriptor::new_bare(ms).unwrap();
1411
1412 bare.satisfy(&mut txin, &satisfier).expect("satisfaction");
1413 assert_eq!(
1414 txin,
1415 bitcoin::TxIn {
1416 previous_output: bitcoin::OutPoint::default(),
1417 script_sig: script::Builder::new()
1418 .push_slice(<&PushBytes>::try_from(sigser.as_slice()).unwrap())
1419 .into_script(),
1420 sequence: Sequence::from_height(100),
1421 witness: Witness::default(),
1422 }
1423 );
1424 assert_eq!(bare.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1425
1426 let pkh = Descriptor::new_pkh(pk).unwrap();
1427 pkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1428 assert_eq!(
1429 txin,
1430 bitcoin::TxIn {
1431 previous_output: bitcoin::OutPoint::default(),
1432 script_sig: script::Builder::new()
1433 .push_slice(<&PushBytes>::try_from(sigser.as_slice()).unwrap())
1434 .push_key(&pk)
1435 .into_script(),
1436 sequence: Sequence::from_height(100),
1437 witness: Witness::default(),
1438 }
1439 );
1440 assert_eq!(pkh.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1441
1442 let wpkh = Descriptor::new_wpkh(pk).unwrap();
1443 wpkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1444 assert_eq!(
1445 txin,
1446 bitcoin::TxIn {
1447 previous_output: bitcoin::OutPoint::default(),
1448 script_sig: bitcoin::ScriptBuf::new(),
1449 sequence: Sequence::from_height(100),
1450 witness: Witness::from_slice(&[sigser.clone(), pk.to_bytes()]),
1451 }
1452 );
1453 assert_eq!(wpkh.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1454
1455 let shwpkh = Descriptor::new_sh_wpkh(pk).unwrap();
1456 shwpkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1457 let redeem_script = script::Builder::new()
1458 .push_opcode(opcodes::all::OP_PUSHBYTES_0)
1459 .push_slice(
1460 hash160::Hash::from_str("d1b2a1faf62e73460af885c687dee3b7189cd8ab")
1461 .unwrap()
1462 .to_byte_array(),
1463 )
1464 .into_script();
1465 assert_eq!(
1466 txin,
1467 bitcoin::TxIn {
1468 previous_output: bitcoin::OutPoint::default(),
1469 script_sig: script::Builder::new()
1470 .push_slice(<&PushBytes>::try_from(redeem_script.as_bytes()).unwrap())
1471 .into_script(),
1472 sequence: Sequence::from_height(100),
1473 witness: Witness::from_slice(&[sigser.clone(), pk.to_bytes()]),
1474 }
1475 );
1476 assert_eq!(
1477 shwpkh.unsigned_script_sig(),
1478 script::Builder::new()
1479 .push_slice(<&PushBytes>::try_from(redeem_script.as_bytes()).unwrap())
1480 .into_script()
1481 );
1482
1483 let ms = ms_str!("c:pk_k({})", pk);
1484 let sh = Descriptor::new_sh(ms.clone()).unwrap();
1485 sh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1486 assert_eq!(
1487 txin,
1488 bitcoin::TxIn {
1489 previous_output: bitcoin::OutPoint::default(),
1490 script_sig: script::Builder::new()
1491 .push_slice(<&PushBytes>::try_from(sigser.as_slice()).unwrap())
1492 .push_slice(<&PushBytes>::try_from(ms.encode().as_bytes()).unwrap())
1493 .into_script(),
1494 sequence: Sequence::from_height(100),
1495 witness: Witness::default(),
1496 }
1497 );
1498 assert_eq!(sh.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1499
1500 let ms = ms_str!("c:pk_k({})", pk);
1501
1502 let wsh = Descriptor::new_wsh(ms.clone()).unwrap();
1503 wsh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1504 assert_eq!(
1505 txin,
1506 bitcoin::TxIn {
1507 previous_output: bitcoin::OutPoint::default(),
1508 script_sig: bitcoin::ScriptBuf::new(),
1509 sequence: Sequence::from_height(100),
1510 witness: Witness::from_slice(&[sigser.clone(), ms.encode().into_bytes()]),
1511 }
1512 );
1513 assert_eq!(wsh.unsigned_script_sig(), bitcoin::ScriptBuf::new());
1514
1515 let shwsh = Descriptor::new_sh_wsh(ms.clone()).unwrap();
1516 shwsh.satisfy(&mut txin, &satisfier).expect("satisfaction");
1517 assert_eq!(
1518 txin,
1519 bitcoin::TxIn {
1520 previous_output: bitcoin::OutPoint::default(),
1521 script_sig: script::Builder::new()
1522 .push_slice(<&PushBytes>::try_from(ms.encode().to_p2wsh().as_bytes()).unwrap())
1523 .into_script(),
1524 sequence: Sequence::from_height(100),
1525 witness: Witness::from_slice(&[sigser.clone(), ms.encode().into_bytes()]),
1526 }
1527 );
1528 assert_eq!(
1529 shwsh.unsigned_script_sig(),
1530 script::Builder::new()
1531 .push_slice(<&PushBytes>::try_from(ms.encode().to_p2wsh().as_bytes()).unwrap())
1532 .into_script()
1533 );
1534 }
1535
1536 #[test]
1537 fn after_is_cltv() {
1538 let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("wsh(after(1000))").unwrap();
1539 let script = descriptor.explicit_script().unwrap();
1540
1541 let actual_instructions: Vec<_> = script.instructions().collect();
1542 let check = actual_instructions.last().unwrap();
1543
1544 assert_eq!(check, &Ok(Instruction::Op(OP_CLTV)))
1545 }
1546
1547 #[test]
1548 fn older_is_csv() {
1549 let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("wsh(older(1000))").unwrap();
1550 let script = descriptor.explicit_script().unwrap();
1551
1552 let actual_instructions: Vec<_> = script.instructions().collect();
1553 let check = actual_instructions.last().unwrap();
1554
1555 assert_eq!(check, &Ok(Instruction::Op(OP_CSV)))
1556 }
1557
1558 #[test]
1559 fn tr_roundtrip_key() {
1560 let script = Tr::<String>::from_str("tr()").unwrap().to_string();
1561 assert_eq!(script, format!("tr()#x4ml3kxd"))
1562 }
1563
1564 #[test]
1565 fn tr_roundtrip_script() {
1566 let descriptor = Tr::<String>::from_str("tr(,{pk(),pk()})")
1567 .unwrap()
1568 .to_string();
1569
1570 assert_eq!(descriptor, "tr(,{pk(),pk()})#7dqr6v8r");
1571
1572 let descriptor = Descriptor::<String>::from_str("tr(A,{pk(B),pk(C)})")
1573 .unwrap()
1574 .to_string();
1575 assert_eq!(descriptor, "tr(A,{pk(B),pk(C)})#y0uc9t6x");
1576 }
1577
1578 #[test]
1579 fn tr_roundtrip_tree() {
1580 let p1 = "020000000000000000000000000000000000000000000000000000000000000001";
1581 let p2 = "020000000000000000000000000000000000000000000000000000000000000002";
1582 let p3 = "020000000000000000000000000000000000000000000000000000000000000003";
1583 let p4 = "020000000000000000000000000000000000000000000000000000000000000004";
1584 let p5 = "03f8551772d66557da28c1de858124f365a8eb30ce6ad79c10e0f4c546d0ab0f82";
1585 let descriptor = Tr::<PublicKey>::from_str(&format!(
1586 "tr({},{{pk({}),{{pk({}),or_d(pk({}),pkh({}))}}}})",
1587 p1, p2, p3, p4, p5
1588 ))
1589 .unwrap();
1590
1591 assert_eq!(
1593 descriptor.to_string(),
1594 format!(
1595 "tr({},{{pk({}),{{pk({}),or_d(pk({}),pkh({}))}}}})#tvu28c0s",
1596 p1, p2, p3, p4, p5
1597 )
1598 );
1599 assert_eq!(
1600 descriptor.spend_info().merkle_root().unwrap().to_string(),
1601 "e1597abcb76f7cbc0792cf04a9c2d4f39caed1ede0afef772064126f28c69b09"
1602 );
1603 }
1604
1605 #[test]
1606 fn tr_script_pubkey() {
1607 let key = Descriptor::<bitcoin::PublicKey>::from_str(
1608 "tr(02e20e746af365e86647826397ba1c0e0d5cb685752976fe2f326ab76bdc4d6ee9)",
1609 )
1610 .unwrap();
1611 assert_eq!(
1612 key.script_pubkey().to_hex_string(),
1613 "51209c19294f03757da3dc235a5960631e3c55751632f5889b06b7a053bdc0bcfbcb"
1614 )
1615 }
1616
1617 #[test]
1618 fn tr_named_branch() {
1619 use crate::{ParseError, ParseTreeError};
1620
1621 assert!(matches!(
1622 StdDescriptor::from_str(
1623 "tr(0202d44008000010100000000084F0000000dd0dd00000000000201dceddd00d00,abc{0,0})"
1624 ),
1625 Err(Error::Parse(ParseError::Tree(ParseTreeError::IncorrectName {
1626 expected: "",
1627 ..
1628 }))),
1629 ));
1630 }
1631
1632 #[test]
1633 fn roundtrip_tests() {
1634 let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("multi");
1635 assert_eq!(descriptor.unwrap_err().to_string(), "expected threshold, found terminal",);
1636 }
1637
1638 #[test]
1639 fn empty_thresh() {
1640 let descriptor = Descriptor::<bitcoin::PublicKey>::from_str("thresh");
1641 assert_eq!(descriptor.unwrap_err().to_string(), "expected threshold, found terminal");
1642 }
1643
1644 #[test]
1645 fn witness_stack_for_andv_is_arranged_in_correct_order() {
1646 let a = bitcoin::PublicKey::from_str(
1648 "02937402303919b3a2ee5edd5009f4236f069bf75667b8e6ecf8e5464e20116a0e",
1649 )
1650 .unwrap();
1651 let sig_a = secp256k1::ecdsa::Signature::from_str("3045022100a7acc3719e9559a59d60d7b2837f9842df30e7edcd754e63227e6168cec72c5d022066c2feba4671c3d99ea75d9976b4da6c86968dbf3bab47b1061e7a1966b1778c").unwrap();
1652
1653 let b = bitcoin::PublicKey::from_str(
1654 "02eb64639a17f7334bb5a1a3aad857d6fec65faef439db3de72f85c88bc2906ad3",
1655 )
1656 .unwrap();
1657 let sig_b = secp256k1::ecdsa::Signature::from_str("3044022075b7b65a7e6cd386132c5883c9db15f9a849a0f32bc680e9986398879a57c276022056d94d12255a4424f51c700ac75122cb354895c9f2f88f0cbb47ba05c9c589ba").unwrap();
1658
1659 let descriptor = Descriptor::<bitcoin::PublicKey>::from_str(&format!(
1660 "wsh(and_v(v:pk({A}),pk({B})))",
1661 A = a,
1662 B = b
1663 ))
1664 .unwrap();
1665
1666 let mut txin = bitcoin::TxIn {
1667 previous_output: bitcoin::OutPoint::default(),
1668 script_sig: bitcoin::ScriptBuf::new(),
1669 sequence: Sequence::ZERO,
1670 witness: Witness::default(),
1671 };
1672 let satisfier = {
1673 let mut satisfier = BTreeMap::new();
1674
1675 satisfier.insert(
1676 a,
1677 bitcoin::ecdsa::Signature { signature: sig_a, sighash_type: EcdsaSighashType::All },
1678 );
1679 satisfier.insert(
1680 b,
1681 bitcoin::ecdsa::Signature { signature: sig_b, sighash_type: EcdsaSighashType::All },
1682 );
1683
1684 satisfier
1685 };
1686
1687 descriptor.satisfy(&mut txin, &satisfier).unwrap();
1689
1690 let wit = txin.witness.to_vec();
1692 let witness0 = &wit[0];
1693 let witness1 = &wit[1];
1694
1695 let sig0 = secp256k1::ecdsa::Signature::from_der(&witness0[..witness0.len() - 1]).unwrap();
1696 let sig1 = secp256k1::ecdsa::Signature::from_der(&witness1[..witness1.len() - 1]).unwrap();
1697
1698 assert_eq!(sig1, sig_a);
1703 assert_eq!(sig0, sig_b);
1704 }
1705
1706 #[test]
1707 fn test_scriptcode() {
1708 let descriptor = Descriptor::<PublicKey>::from_str(
1710 "wpkh(025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357)",
1711 )
1712 .unwrap();
1713 assert_eq!(
1714 *descriptor.script_code().unwrap().as_bytes(),
1715 hex::decode_to_vec("76a9141d0f172a0ecb48aee1be1f2687d2963ae33f71a188ac").unwrap()[..]
1716 );
1717
1718 let descriptor = Descriptor::<PublicKey>::from_str(
1720 "sh(wpkh(03ad1d8e89212f0b92c74d23bb710c00662ad1470198ac48c43f7d6f93a2a26873))",
1721 )
1722 .unwrap();
1723 assert_eq!(
1724 *descriptor.script_code().unwrap().as_bytes(),
1725 hex::decode_to_vec("76a91479091972186c449eb1ded22b78e40d009bdf008988ac").unwrap()[..]
1726 );
1727
1728 let descriptor = Descriptor::<PublicKey>::from_str(
1730 "wsh(multi(2,03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd,03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626))",
1731 )
1732 .unwrap();
1733 assert_eq!(
1734 *descriptor
1735 .script_code().unwrap()
1736 .as_bytes(),
1737 hex::decode_to_vec("522103789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd2103dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a6162652ae").unwrap()[..]
1738 );
1739
1740 let descriptor = Descriptor::<PublicKey>::from_str("sh(wsh(multi(2,03789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd,03dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a61626)))").unwrap();
1742 assert_eq!(
1743 *descriptor
1744 .script_code().unwrap()
1745 .as_bytes(),
1746 hex::decode_to_vec("522103789ed0bb717d88f7d321a368d905e7430207ebbd82bd342cf11ae157a7ace5fd2103dbc6764b8884a92e871274b87583e6d5c2a58819473e17e107ef3f6aa5a6162652ae")
1747 .unwrap()[..]
1748 );
1749 }
1750
1751 #[test]
1752 fn parse_descriptor_key() {
1753 let key = "[78412e3a/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*";
1755 let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1756 origin: Some((
1757 bip32::Fingerprint::from([0x78, 0x41, 0x2e, 0x3a]),
1758 (&[
1759 bip32::ChildNumber::from_hardened_idx(44).unwrap(),
1760 bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1761 bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1762 ][..])
1763 .into(),
1764 )),
1765 xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1766 derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1767 wildcard: Wildcard::Unhardened,
1768 });
1769 assert_eq!(expected, key.parse().unwrap());
1770 assert_eq!(format!("{}", expected), key);
1771
1772 let key = "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1";
1774 let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1775 origin: None,
1776 xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1777 derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1778 wildcard: Wildcard::None,
1779 });
1780 assert_eq!(expected, key.parse().unwrap());
1781 assert_eq!(format!("{}", expected), key);
1782
1783 let key = "tpubD6NzVbkrYhZ4YqYr3amYH15zjxHvBkUUeadieW8AxTZC7aY2L8aPSk3tpW6yW1QnWzXAB7zoiaNMfwXPPz9S68ZCV4yWvkVXjdeksLskCed/1";
1785 let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1786 origin: None,
1787 xkey: bip32::Xpub::from_str("tpubD6NzVbkrYhZ4YqYr3amYH15zjxHvBkUUeadieW8AxTZC7aY2L8aPSk3tpW6yW1QnWzXAB7zoiaNMfwXPPz9S68ZCV4yWvkVXjdeksLskCed").unwrap(),
1788 derivation_path: (&[bip32::ChildNumber::from_normal_idx(1).unwrap()][..]).into(),
1789 wildcard: Wildcard::None,
1790 });
1791 assert_eq!(expected, key.parse().unwrap());
1792 assert_eq!(format!("{}", expected), key);
1793
1794 let key = "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL";
1796 let expected = DescriptorPublicKey::XPub(DescriptorXKey {
1797 origin: None,
1798 xkey: bip32::Xpub::from_str("xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL").unwrap(),
1799 derivation_path: bip32::DerivationPath::from(&[][..]),
1800 wildcard: Wildcard::None,
1801 });
1802 assert_eq!(expected, key.parse().unwrap());
1803 assert_eq!(format!("{}", expected), key);
1804
1805 let key = "03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8";
1807 let expected = DescriptorPublicKey::Single(SinglePub {
1808 key: SinglePubKey::FullKey(
1809 bitcoin::PublicKey::from_str(
1810 "03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8",
1811 )
1812 .unwrap(),
1813 ),
1814 origin: None,
1815 });
1816 assert_eq!(expected, key.parse().unwrap());
1817 assert_eq!(format!("{}", expected), key);
1818
1819 let key = "04f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446a";
1821 let expected = DescriptorPublicKey::Single(SinglePub {
1822 key: SinglePubKey::FullKey(bitcoin::PublicKey::from_str(
1823 "04f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446a",
1824 )
1825 .unwrap()),
1826 origin: None,
1827 });
1828 assert_eq!(expected, key.parse().unwrap());
1829 assert_eq!(format!("{}", expected), key);
1830
1831 let desc =
1833 "[78412e3a/0'/42/0']0231c7d3fc85c148717848033ce276ae2b464a4e2c367ed33886cc428b8af48ff8";
1834 let expected = DescriptorPublicKey::Single(SinglePub {
1835 key: SinglePubKey::FullKey(
1836 bitcoin::PublicKey::from_str(
1837 "0231c7d3fc85c148717848033ce276ae2b464a4e2c367ed33886cc428b8af48ff8",
1838 )
1839 .unwrap(),
1840 ),
1841 origin: Some((
1842 bip32::Fingerprint::from([0x78, 0x41, 0x2e, 0x3a]),
1843 (&[
1844 bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1845 bip32::ChildNumber::from_normal_idx(42).unwrap(),
1846 bip32::ChildNumber::from_hardened_idx(0).unwrap(),
1847 ][..])
1848 .into(),
1849 )),
1850 });
1851 assert_eq!(expected, desc.parse().expect("Parsing desc"));
1852 assert_eq!(format!("{}", expected), desc);
1853 }
1854
1855 #[test]
1856 fn test_sortedmulti() {
1857 fn _test_sortedmulti(raw_desc_one: &str, raw_desc_two: &str, raw_addr_expected: &str) {
1858 let secp_ctx = secp256k1::Secp256k1::verification_only();
1859 let index = 5;
1860
1861 let desc_one = Descriptor::<DescriptorPublicKey>::from_str(raw_desc_one).unwrap();
1863 let desc_two = Descriptor::<DescriptorPublicKey>::from_str(raw_desc_two).unwrap();
1864
1865 assert_eq!(desc_one.to_string(), raw_desc_one);
1867 assert_eq!(desc_two.to_string(), raw_desc_two);
1868
1869 let addr_one = desc_one
1871 .at_derivation_index(index)
1872 .unwrap()
1873 .derived_descriptor(&secp_ctx)
1874 .address(bitcoin::Network::Bitcoin)
1875 .unwrap();
1876 let addr_two = desc_two
1877 .at_derivation_index(index)
1878 .unwrap()
1879 .derived_descriptor(&secp_ctx)
1880 .address(bitcoin::Network::Bitcoin)
1881 .unwrap();
1882 let addr_expected = bitcoin::Address::from_str(raw_addr_expected)
1883 .unwrap()
1884 .assume_checked();
1885 assert_eq!(addr_one, addr_expected);
1886 assert_eq!(addr_two, addr_expected);
1887 }
1888
1889 _test_sortedmulti(
1891 "sh(sortedmulti(1,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352))#uetvewm2",
1892 "sh(sortedmulti(1,0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))#7l8smyg9",
1893 "3JZJNxvDKe6Y55ZaF5223XHwfF2eoMNnoV",
1894 );
1895
1896 _test_sortedmulti(
1898 "wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#7etm7zk7",
1899 "wsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB))#ppmeel9k",
1900 "bc1qpq2cfgz5lktxzr5zqv7nrzz46hsvq3492ump9pz8rzcl8wqtwqcspx5y6a",
1901 );
1902
1903 _test_sortedmulti(
1905 "sh(wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*)))#u60cee0u",
1906 "sh(wsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*)))#75dkf44w",
1907 "325zcVBN5o2eqqqtGwPjmtDd8dJRyYP82s",
1908 );
1909 }
1910
1911 #[test]
1912 fn test_parse_descriptor() {
1913 let secp = &secp256k1::Secp256k1::signing_only();
1914 let (descriptor, key_map) = Descriptor::parse_descriptor(secp, "wpkh(tprv8ZgxMBicQKsPcwcD4gSnMti126ZiETsuX7qwrtMypr6FBwAP65puFn4v6c3jrN9VwtMRMph6nyT63NrfUL4C3nBzPcduzVSuHD7zbX2JKVc/44'/0'/0'/0/*)").unwrap();
1915 assert_eq!(descriptor.to_string(), "wpkh([2cbe2a6d/44'/0'/0']tpubDCvNhURocXGZsLNqWcqD3syHTqPXrMSTwi8feKVwAcpi29oYKsDD3Vex7x2TDneKMVN23RbLprfxB69v94iYqdaYHsVz3kPR37NQXeqouVz/0/*)#nhdxg96s");
1916 assert_eq!(key_map.len(), 1);
1917
1918 macro_rules! check_invalid_checksum {
1920 ($secp: ident,$($desc: expr),*) => {
1921 use crate::{ParseError, ParseTreeError};
1922 $(
1923 match Descriptor::parse_descriptor($secp, $desc) {
1924 Err(Error::Parse(ParseError::Tree(ParseTreeError::Checksum(_)))) => {},
1925 Err(e) => panic!("Expected bad checksum for {}, got '{}'", $desc, e),
1926 _ => panic!("Invalid checksum treated as valid: {}", $desc),
1927 };
1928 )*
1929 };
1930 }
1931 check_invalid_checksum!(secp,
1932 "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#",
1933 "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#",
1934 "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfyq",
1935 "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5tq",
1936 "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxf",
1937 "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5",
1938 "sh(multi(3,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfy",
1939 "sh(multi(3,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t",
1940 "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjq09x4t",
1941 "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))##ggssrxfy",
1942 "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))##tjq09x4t"
1943 );
1944
1945 Descriptor::parse_descriptor(secp, "sh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#ggrsrxfy").expect("Valid descriptor with checksum");
1946 Descriptor::parse_descriptor(secp, "sh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#tjg09x5t").expect("Valid descriptor with checksum");
1947 }
1948
1949 #[test]
1950 #[cfg(feature = "compiler")]
1951 fn parse_and_derive() {
1952 let descriptor_str = "thresh(2,\
1953pk([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/*),\
1954pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1),\
1955pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
1956 let policy: policy::concrete::Policy<DescriptorPublicKey> = descriptor_str.parse().unwrap();
1957 let descriptor = Descriptor::new_sh(policy.compile().unwrap()).unwrap();
1958 let definite_descriptor = descriptor.at_derivation_index(42).unwrap();
1959
1960 let res_descriptor_str = "thresh(2,\
1961pk([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1/42),\
1962pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1),\
1963pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
1964 let res_policy: policy::concrete::Policy<DescriptorPublicKey> =
1965 res_descriptor_str.parse().unwrap();
1966 let res_descriptor = Descriptor::new_sh(res_policy.compile().unwrap()).unwrap();
1967
1968 assert_eq!(res_descriptor.to_string(), definite_descriptor.to_string());
1969 }
1970
1971 #[test]
1972 fn parse_with_secrets() {
1973 let secp = &secp256k1::Secp256k1::signing_only();
1974 let descriptor_str = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)#v20xlvm9";
1975 let (descriptor, keymap) =
1976 Descriptor::<DescriptorPublicKey>::parse_descriptor(secp, descriptor_str).unwrap();
1977
1978 let expected = "wpkh([a12b02f4/44'/0'/0']xpub6BzhLAQUDcBUfHRQHZxDF2AbcJqp4Kaeq6bzJpXrjrWuK26ymTFwkEFbxPra2bJ7yeZKbDjfDeFwxe93JMqpo5SsPJH6dZdvV9kMzJkAZ69/0/*)#u37l7u8u";
1979 assert_eq!(expected, descriptor.to_string());
1980 assert_eq!(keymap.len(), 1);
1981
1982 assert_eq!(descriptor_str, descriptor.to_string_with_secret(&keymap));
1984 }
1985
1986 #[test]
1987 fn checksum_for_nested_sh() {
1988 let descriptor_str = "sh(wpkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL))";
1989 let descriptor: Descriptor<DescriptorPublicKey> = descriptor_str.parse().unwrap();
1990 assert_eq!(descriptor.to_string(), "sh(wpkh(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL))#tjp2zm88");
1991
1992 let descriptor_str = "sh(wsh(pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))";
1993 let descriptor: Descriptor<DescriptorPublicKey> = descriptor_str.parse().unwrap();
1994 assert_eq!(descriptor.to_string(), "sh(wsh(pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))#6c6hwr22");
1995 }
1996
1997 #[test]
1998 fn test_xonly_keys() {
1999 let comp_key = "0308c0fcf8895f4361b4fc77afe2ad53b0bd27dcebfd863421b2b246dc283d4103";
2000 let x_only_key = "08c0fcf8895f4361b4fc77afe2ad53b0bd27dcebfd863421b2b246dc283d4103";
2001
2002 Descriptor::<DescriptorPublicKey>::from_str(&format!("tr({})", comp_key)).unwrap();
2004 Descriptor::<DescriptorPublicKey>::from_str(&format!("tr({})", x_only_key)).unwrap();
2005
2006 Descriptor::<DescriptorPublicKey>::from_str(&format!("wsh(pk({}))", comp_key)).unwrap();
2008 Descriptor::<DescriptorPublicKey>::from_str(&format!("wsh(pk({}))", x_only_key))
2009 .unwrap_err();
2010 }
2011
2012 #[test]
2013 fn test_find_derivation_index_for_spk() {
2014 let secp = secp256k1::Secp256k1::verification_only();
2015 let descriptor = Descriptor::from_str("tr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)").unwrap();
2016 let script_at_0_1 = ScriptBuf::from_hex(
2017 "5120a82f29944d65b86ae6b5e5cc75e294ead6c59391a1edc5e016e3498c67fc7bbb",
2018 )
2019 .unwrap();
2020 let expected_concrete = Descriptor::from_str(
2021 "tr(0283dfe85a3151d2517290da461fe2815591ef69f2b18a2ce63f01697a8b313145)",
2022 )
2023 .unwrap();
2024
2025 assert_eq!(descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..1), Ok(None));
2026 assert_eq!(
2027 descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..2),
2028 Ok(Some((1, expected_concrete.clone())))
2029 );
2030 assert_eq!(
2031 descriptor.find_derivation_index_for_spk(&secp, &script_at_0_1, 0..10),
2032 Ok(Some((1, expected_concrete)))
2033 );
2034 }
2035
2036 #[test]
2037 fn display_alternate() {
2038 let bare = StdDescriptor::from_str(
2039 "pk(020000000000000000000000000000000000000000000000000000000000000002)",
2040 )
2041 .unwrap();
2042 assert_eq!(
2043 format!("{}", bare),
2044 "pk(020000000000000000000000000000000000000000000000000000000000000002)#7yxkn84h",
2045 );
2046 assert_eq!(
2047 format!("{:#}", bare),
2048 "pk(020000000000000000000000000000000000000000000000000000000000000002)",
2049 );
2050
2051 let pkh = StdDescriptor::from_str(
2052 "pkh(020000000000000000000000000000000000000000000000000000000000000002)",
2053 )
2054 .unwrap();
2055 assert_eq!(
2056 format!("{}", pkh),
2057 "pkh(020000000000000000000000000000000000000000000000000000000000000002)#ma7nspkf",
2058 );
2059 assert_eq!(
2060 format!("{:#}", pkh),
2061 "pkh(020000000000000000000000000000000000000000000000000000000000000002)",
2062 );
2063
2064 let wpkh = StdDescriptor::from_str(
2065 "wpkh(020000000000000000000000000000000000000000000000000000000000000002)",
2066 )
2067 .unwrap();
2068 assert_eq!(
2069 format!("{}", wpkh),
2070 "wpkh(020000000000000000000000000000000000000000000000000000000000000002)#d3xz2xye",
2071 );
2072 assert_eq!(
2073 format!("{:#}", wpkh),
2074 "wpkh(020000000000000000000000000000000000000000000000000000000000000002)",
2075 );
2076
2077 let shwpkh = StdDescriptor::from_str(
2078 "sh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))",
2079 )
2080 .unwrap();
2081 assert_eq!(
2082 format!("{}", shwpkh),
2083 "sh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))#45zpjtet",
2084 );
2085 assert_eq!(
2086 format!("{:#}", shwpkh),
2087 "sh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))",
2088 );
2089
2090 let wsh = StdDescriptor::from_str("wsh(1)").unwrap();
2091 assert_eq!(format!("{}", wsh), "wsh(1)#mrg7xj7p");
2092 assert_eq!(format!("{:#}", wsh), "wsh(1)");
2093
2094 let sh = StdDescriptor::from_str("sh(1)").unwrap();
2095 assert_eq!(format!("{}", sh), "sh(1)#l8r75ggs");
2096 assert_eq!(format!("{:#}", sh), "sh(1)");
2097
2098 let shwsh = StdDescriptor::from_str("sh(wsh(1))").unwrap();
2099 assert_eq!(format!("{}", shwsh), "sh(wsh(1))#hcyfl07f");
2100 assert_eq!(format!("{:#}", shwsh), "sh(wsh(1))");
2101
2102 let tr = StdDescriptor::from_str(
2103 "tr(020000000000000000000000000000000000000000000000000000000000000002)",
2104 )
2105 .unwrap();
2106 assert_eq!(
2107 format!("{}", tr),
2108 "tr(020000000000000000000000000000000000000000000000000000000000000002)#8hc7wq5h",
2109 );
2110 assert_eq!(
2111 format!("{:#}", tr),
2112 "tr(020000000000000000000000000000000000000000000000000000000000000002)",
2113 );
2114 }
2115
2116 #[test]
2117 fn multipath_descriptors() {
2118 let desc = Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<7';8h;20>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/<0;1;987>/*)))").unwrap();
2120 assert!(desc.is_multipath());
2121 assert_eq!(desc.into_single_descriptors().unwrap(), vec![
2122 Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/7'/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/0/*)))").unwrap(),
2123 Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/8h/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/1/*)))").unwrap(),
2124 Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/20/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/987/*)))").unwrap()
2125 ]);
2126
2127 let desc = Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap();
2129 assert!(desc.is_multipath());
2130 assert_eq!(desc.into_single_descriptors().unwrap(), vec![
2131 Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/0/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap(),
2132 Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/1/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap(),
2133 ]);
2134
2135 let notmulti_desc = Descriptor::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/4567/*)))").unwrap();
2137 assert!(!notmulti_desc.is_multipath());
2138 assert_eq!(notmulti_desc.clone().into_single_descriptors().unwrap(), vec![notmulti_desc]);
2139
2140 Descriptor::<DescriptorPublicKey>::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/<0;1;2;3;4>/*)))").unwrap_err();
2142 Descriptor::<DescriptorPublicKey>::from_str("wsh(andor(pk(tpubDEN9WSToTyy9ZQfaYqSKfmVqmq1VVLNtYfj3Vkqh67et57eJ5sTKZQBkHqSwPUsoSskJeaYnPttHe2VrkCsKA27kUaN9SDc5zhqeLzKa1rr/0'/<0;1;2;3>/*),older(10000),pk(tpubD8LYfn6njiA2inCoxwM7EuN3cuLVcaHAwLYeups13dpevd3nHLRdK9NdQksWXrhLQVxcUZRpnp5CkJ1FhE61WRAsHxDNAkvGkoQkAeWDYjV/8/<0;1;2>/*)))").unwrap_err();
2143 }
2144
2145 #[test]
2146 fn regression_736() {
2147 Descriptor::<DescriptorPublicKey>::from_str(
2148 "tr(0000000000000000000000000000000000000000000000000000000000000002,)",
2149 )
2150 .unwrap_err();
2151 }
2152
2153 #[test]
2154 fn regression_734() {
2155 Descriptor::<DescriptorPublicKey>::from_str(
2156 "wsh(or_i(pk(0202baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a66a),1))",
2157 )
2158 .unwrap();
2159 Descriptor::<DescriptorPublicKey>::from_str(
2160 "sh(or_i(pk(0202baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a66a),1))",
2161 )
2162 .unwrap();
2163 Descriptor::<DescriptorPublicKey>::from_str(
2164 "tr(02baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0a66a,1)",
2165 )
2166 .unwrap_err();
2167 }
2168
2169 #[test]
2170 fn tr_lift() {
2171 use crate::policy::Liftable as _;
2172
2173 let desc = Descriptor::<String>::from_str("tr(ROOT,{pk(A1),{pk(B1),pk(B2)}})").unwrap();
2175 let lift = desc.lift().unwrap();
2176 assert_eq!(lift.to_string(), "or(pk(ROOT),or(pk(A1),pk(B1),pk(B2)))",);
2177 let desc = Descriptor::<String>::from_str("tr(ROOT,{{pk(A1),pk(B1)},pk(B2)})").unwrap();
2178 let lift = desc.lift().unwrap();
2179 assert_eq!(lift.to_string(), "or(pk(ROOT),or(pk(A1),pk(B1),pk(B2)))",);
2180
2181 let desc = Descriptor::<String>::from_str("tr(ROOT,{0,{0,0}})").unwrap();
2183 let lift = desc.lift().unwrap();
2184 assert_eq!(lift.to_string(), "or(pk(ROOT),UNSATISFIABLE)",);
2185 }
2186
2187 #[test]
2188 fn test_context_pks() {
2189 let comp_key = bitcoin::PublicKey::from_str(
2190 "02015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab",
2191 )
2192 .unwrap();
2193 let x_only_key = bitcoin::key::XOnlyPublicKey::from_str(
2194 "015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab",
2195 )
2196 .unwrap();
2197 let uncomp_key = bitcoin::PublicKey::from_str("04015e4cb53458bf813db8c79968e76e10d13ed6426a23fa71c2f41ba021c2a7ab0d46021e9e69ef061eb25eab41ae206187b2b05e829559df59d78319bd9267b4").unwrap();
2198
2199 type Desc = Descriptor<DescriptorPublicKey>;
2200
2201 Desc::from_str(&format!("sh(pk({}))", comp_key)).unwrap();
2203 Desc::from_str(&format!("sh(pk({}))", uncomp_key)).unwrap();
2204 Desc::from_str(&format!("sh(pk({}))", x_only_key)).unwrap_err();
2205
2206 Desc::from_str(&format!("pk({})", comp_key)).unwrap();
2208 Desc::from_str(&format!("pk({})", uncomp_key)).unwrap();
2209 Desc::from_str(&format!("pk({})", x_only_key)).unwrap_err();
2210
2211 Desc::from_str(&format!("pkh({})", comp_key)).unwrap();
2213 Desc::from_str(&format!("pkh({})", uncomp_key)).unwrap();
2214 Desc::from_str(&format!("pkh({})", x_only_key)).unwrap_err();
2215
2216 Desc::from_str(&format!("wpkh({})", comp_key)).unwrap();
2218 Desc::from_str(&format!("wpkh({})", uncomp_key)).unwrap_err();
2219 Desc::from_str(&format!("wpkh({})", x_only_key)).unwrap_err();
2220
2221 Desc::from_str(&format!("wsh(pk({}))", comp_key)).unwrap();
2223 Desc::from_str(&format!("wsh(pk({}))", uncomp_key)).unwrap_err();
2224 Desc::from_str(&format!("wsh(pk({}))", x_only_key)).unwrap_err();
2225
2226 Desc::from_str(&format!("tr({})", comp_key)).unwrap();
2228 Desc::from_str(&format!("tr({})", uncomp_key)).unwrap_err();
2229 Desc::from_str(&format!("tr({})", x_only_key)).unwrap();
2230
2231 Desc::from_str(&format!("tr({},pk({}))", x_only_key, comp_key)).unwrap();
2233 Desc::from_str(&format!("tr({},pk({}))", x_only_key, uncomp_key)).unwrap_err();
2234 Desc::from_str(&format!("tr({},pk({}))", x_only_key, x_only_key)).unwrap();
2235 }
2236
2237 #[test]
2238 fn regression_806() {
2239 let secp = secp256k1::Secp256k1::signing_only();
2240 type Desc = Descriptor<DescriptorPublicKey>;
2241 Desc::from_str("pkh(111111111111111111111111111111110000008375319363688624584A111111)")
2243 .unwrap_err();
2244 Desc::parse_descriptor(
2246 &secp,
2247 "pkh(111111111111111111111111111111110000008375319363688624584A111111)",
2248 )
2249 .unwrap_err();
2250 }
2251
2252 #[test]
2253 fn convert_public_key_descriptor_to_definite_key() {
2254 let descriptor_str = "wsh(or_d(pk(021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b),pk(0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6)))";
2255 let full_pk_descriptor: Descriptor<PublicKey> =
2256 Descriptor::from_str(descriptor_str).unwrap();
2257
2258 struct TranslateFullPk;
2259
2260 impl Translator<bitcoin::PublicKey> for TranslateFullPk {
2261 type TargetPk = DefiniteDescriptorKey;
2262 type Error = core::convert::Infallible;
2263
2264 fn pk(
2265 &mut self,
2266 pk: &bitcoin::PublicKey,
2267 ) -> Result<DefiniteDescriptorKey, Self::Error> {
2268 Ok(DefiniteDescriptorKey::new(DescriptorPublicKey::from(*pk))
2269 .expect("DescriptorPublicKey from PublicKey has no wildcards"))
2270 }
2271
2272 translate_hash_clone!(bitcoin::PublicKey, DefiniteDescriptorKey, Self::Error);
2273 }
2274
2275 let converted_descriptor = full_pk_descriptor
2276 .translate_pk(&mut TranslateFullPk)
2277 .expect("infallible");
2278
2279 assert_eq!(full_pk_descriptor.to_string(), converted_descriptor.to_string());
2280
2281 let xonly_descriptor_str = "tr(1d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b,pk(02c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6))";
2282 let xonly_pk_descriptor: Descriptor<XOnlyPublicKey> =
2283 Descriptor::from_str(xonly_descriptor_str).unwrap();
2284
2285 struct TranslateXOnlyPk;
2286
2287 impl Translator<XOnlyPublicKey> for TranslateXOnlyPk {
2288 type TargetPk = DefiniteDescriptorKey;
2289 type Error = core::convert::Infallible;
2290
2291 fn pk(&mut self, pk: &XOnlyPublicKey) -> Result<DefiniteDescriptorKey, Self::Error> {
2292 Ok(DefiniteDescriptorKey::new(DescriptorPublicKey::from(*pk))
2293 .expect("DescriptorPublicKey from XOnlyPublicKey has no wildcards"))
2294 }
2295
2296 translate_hash_clone!(XOnlyPublicKey, DefiniteDescriptorKey, Self::Error);
2297 }
2298
2299 let xonly_converted_descriptor = xonly_pk_descriptor
2300 .translate_pk(&mut TranslateXOnlyPk)
2301 .expect("infallible");
2302
2303 assert_eq!(xonly_pk_descriptor.to_string(), xonly_converted_descriptor.to_string());
2304 }
2305
2306 #[test]
2307 fn test_iter_pk() {
2308 let bare_desc = Descriptor::<PublicKey>::from_str(
2310 "pk(020000000000000000000000000000000000000000000000000000000000000002)",
2311 )
2312 .unwrap();
2313 let keys: Vec<_> = bare_desc.iter_pk().collect();
2314 assert_eq!(keys.len(), 1);
2315 assert_eq!(
2316 keys[0].to_string(),
2317 "020000000000000000000000000000000000000000000000000000000000000002"
2318 );
2319
2320 let pkh_desc = Descriptor::<PublicKey>::from_str(
2322 "pkh(020000000000000000000000000000000000000000000000000000000000000002)",
2323 )
2324 .unwrap();
2325 let keys: Vec<_> = pkh_desc.iter_pk().collect();
2326 assert_eq!(keys.len(), 1);
2327 assert_eq!(
2328 keys[0].to_string(),
2329 "020000000000000000000000000000000000000000000000000000000000000002"
2330 );
2331
2332 let wpkh_desc = Descriptor::<PublicKey>::from_str(
2334 "wpkh(020000000000000000000000000000000000000000000000000000000000000002)",
2335 )
2336 .unwrap();
2337 let keys: Vec<_> = wpkh_desc.iter_pk().collect();
2338 assert_eq!(keys.len(), 1);
2339 assert_eq!(
2340 keys[0].to_string(),
2341 "020000000000000000000000000000000000000000000000000000000000000002"
2342 );
2343
2344 let sh_desc = Descriptor::<PublicKey>::from_str(
2346 "sh(or_d(pk(021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b),pk(0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6)))"
2347 ).unwrap();
2348 let keys: Vec<_> = sh_desc.iter_pk().collect();
2349 assert_eq!(keys.len(), 2);
2350 assert_eq!(
2351 keys[0].to_string(),
2352 "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b"
2353 );
2354 assert_eq!(
2355 keys[1].to_string(),
2356 "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6"
2357 );
2358
2359 let shwpkh_desc = Descriptor::<PublicKey>::from_str(
2361 "sh(wpkh(020000000000000000000000000000000000000000000000000000000000000002))",
2362 )
2363 .unwrap();
2364 let keys: Vec<_> = shwpkh_desc.iter_pk().collect();
2365 assert_eq!(keys.len(), 1);
2366 assert_eq!(
2367 keys[0].to_string(),
2368 "020000000000000000000000000000000000000000000000000000000000000002"
2369 );
2370
2371 let shwsh_desc = Descriptor::<PublicKey>::from_str(
2373 "sh(wsh(or_d(pk(021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b),pk(0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6))))"
2374 ).unwrap();
2375 let keys: Vec<_> = shwsh_desc.iter_pk().collect();
2376 assert_eq!(keys.len(), 2);
2377 assert_eq!(
2378 keys[0].to_string(),
2379 "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b"
2380 );
2381 assert_eq!(
2382 keys[1].to_string(),
2383 "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6"
2384 );
2385
2386 let wsh_desc = Descriptor::<PublicKey>::from_str(
2388 "wsh(or_d(pk(021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b),pk(0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6)))"
2389 ).unwrap();
2390 let keys: Vec<_> = wsh_desc.iter_pk().collect();
2391 assert_eq!(keys.len(), 2);
2392 assert_eq!(
2393 keys[0].to_string(),
2394 "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b"
2395 );
2396 assert_eq!(
2397 keys[1].to_string(),
2398 "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6"
2399 );
2400
2401 let sortedmulti_desc = Descriptor::<PublicKey>::from_str(
2403 "sh(sortedmulti(2,021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b,0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))"
2404 ).unwrap();
2405 let keys: Vec<_> = sortedmulti_desc.iter_pk().collect();
2406 assert_eq!(keys.len(), 3);
2407 assert!(keys.iter().any(|k| k.to_string()
2409 == "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b"));
2410 assert!(keys.iter().any(|k| k.to_string()
2411 == "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6"));
2412 assert!(keys.iter().any(|k| k.to_string()
2413 == "03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556"));
2414
2415 let tr_key_only_desc = Descriptor::<PublicKey>::from_str(
2417 "tr(020000000000000000000000000000000000000000000000000000000000000002)",
2418 )
2419 .unwrap();
2420 let keys: Vec<_> = tr_key_only_desc.iter_pk().collect();
2421 assert_eq!(keys.len(), 1);
2422 assert_eq!(
2423 keys[0].to_string(),
2424 "020000000000000000000000000000000000000000000000000000000000000002"
2425 );
2426
2427 let internal_key = "020000000000000000000000000000000000000000000000000000000000000002";
2430 let script_key1 = "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b";
2431 let script_key2 = "0302c8bbbb393f32c843149ce36d56405595aaabab2d0e1f4ca5f9de67dd7419f6";
2432
2433 let tr_with_script_desc = Descriptor::<PublicKey>::from_str(&format!(
2434 "tr({},{{pk({}),pk({})}})",
2435 internal_key, script_key1, script_key2,
2436 ))
2437 .unwrap();
2438
2439 let keys: Vec<_> = tr_with_script_desc.iter_pk().collect();
2440 assert_eq!(keys.len(), 3);
2441
2442 assert_eq!(keys[0].to_string(), internal_key);
2444
2445 assert!(keys[1..].iter().any(|k| k.to_string() == script_key1));
2447 assert!(keys[1..].iter().any(|k| k.to_string() == script_key2));
2448
2449 let tr_complex_desc = Descriptor::<PublicKey>::from_str(&format!(
2451 "tr({},{{pk({}),{{pk({}),or_d(pk({}),pk({}))}}}})",
2452 internal_key,
2453 script_key1,
2454 script_key2,
2455 "03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556",
2456 "0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352"
2457 ))
2458 .unwrap();
2459
2460 let keys: Vec<_> = tr_complex_desc.iter_pk().collect();
2461 assert_eq!(keys.len(), 5);
2462
2463 assert_eq!(keys[0].to_string(), internal_key);
2465
2466 assert!(keys[1..].iter().any(|k| k.to_string() == script_key1));
2468 assert!(keys[1..].iter().any(|k| k.to_string() == script_key2));
2469 assert!(keys[1..].iter().any(|k| k.to_string()
2470 == "03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556"));
2471 assert!(keys[1..].iter().any(|k| k.to_string()
2472 == "0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352"));
2473 }
2474
2475 fn test_keys() -> (Vec<&'static str>, Vec<&'static str>, Vec<&'static str>) {
2477 let mainnet_xpubs = vec![
2479 "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8",
2480 "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ",
2481 "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB",
2482 "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH",
2483 ];
2484
2485 let testnet_tpubs = vec![
2487 "tpubDBrgjcxBxnXyL575sHdkpKohWu5qHKoQ7TJXKNrYznh5fVEGBv89hA8ENW7A8MFVpFUSvgLqc4Nj1WZcpePX6rrxviVtPowvMuGF5rdT2Vi",
2488 "tpubD6NzVbkrYhZ4WQdzxL7NmJN7b85ePo4p6RSj9QQHF7te2RR9iUeVSGgnGkoUsB9LBRosgvNbjRv9bcsJgzgBd7QKuxDm23ZewkTRzNSLEDr",
2489 "tpubD6NzVbkrYhZ4YqYr3amYH15zjxHvBkUUeadieW8AxTZC7aY2L8aPSk3tpW6yW1QnWzXAB7zoiaNMfwXPPz9S68ZCV4yWvkVXjdeksLskCed",
2490 "tpubDCvNhURocXGZsLNqWcqD3syHTqPXrMSTwi8feKVwAcpi29oYKsDD3Vex7x2TDneKMVN23RbLprfxB69v94iYqdaYHsVz3kPR37NQXeqouVz",
2491 ];
2492
2493 let single_keys = vec![
2495 "021d4ea7132d4e1a362ee5efd8d0b59dd4d1fe8906eefa7dd812b05a46b73d829b",
2496 "025476c2e83188368da1ff3e292e7acafcdb3566bb0ad253f62fc70f07aeee6357",
2497 "022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01",
2498 "023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb",
2499 ];
2500
2501 (mainnet_xpubs, testnet_tpubs, single_keys)
2502 }
2503
2504 #[test]
2505 fn test_descriptor_pubkey_xkey_network() {
2506 use core::str::FromStr;
2507
2508 use bitcoin::NetworkKind;
2509
2510 use crate::descriptor::{DescriptorPublicKey, XKeyNetwork};
2511
2512 let (mainnet_xpubs, testnet_tpubs, single_keys) = test_keys();
2513
2514 let basic_tests = vec![
2516 (format!("wpkh({})", mainnet_xpubs[0]), XKeyNetwork::Single(NetworkKind::Main)),
2518 (format!("wpkh({})", testnet_tpubs[0]), XKeyNetwork::Single(NetworkKind::Test)),
2520 (format!("wpkh({})", single_keys[0]), XKeyNetwork::NoXKeys),
2522 ];
2523
2524 for (desc_str, expected) in basic_tests {
2525 let desc = Descriptor::<DescriptorPublicKey>::from_str(&desc_str).unwrap();
2526 assert_eq!(desc.xkey_network(), expected, "Failed for basic descriptor: {}", desc_str);
2527 }
2528
2529 let multi_key_tests = vec![
2531 (
2533 format!("wsh(multi(2,{},{}))", mainnet_xpubs[0], testnet_tpubs[0]),
2534 XKeyNetwork::Mixed,
2535 ),
2536 (
2538 format!("wsh(multi(2,{},{}))", mainnet_xpubs[0], mainnet_xpubs[1]),
2539 XKeyNetwork::Single(NetworkKind::Main),
2540 ),
2541 (
2543 format!(
2544 "wsh(multi(2,{},{},{}))",
2545 testnet_tpubs[0], testnet_tpubs[1], testnet_tpubs[2]
2546 ),
2547 XKeyNetwork::Single(NetworkKind::Test),
2548 ),
2549 (
2551 format!(
2552 "wsh(sortedmulti(2,{},{},{}))",
2553 mainnet_xpubs[0], testnet_tpubs[0], single_keys[0]
2554 ),
2555 XKeyNetwork::Mixed,
2556 ),
2557 (
2559 format!(
2560 "wsh(multi(3,{},{},{},{}))",
2561 mainnet_xpubs[0], mainnet_xpubs[1], mainnet_xpubs[2], mainnet_xpubs[3]
2562 ),
2563 XKeyNetwork::Single(NetworkKind::Main),
2564 ),
2565 ];
2566
2567 for (desc_str, expected) in multi_key_tests {
2568 let desc = Descriptor::<DescriptorPublicKey>::from_str(&desc_str).unwrap();
2569 assert_eq!(
2570 desc.xkey_network(),
2571 expected,
2572 "Failed for multi-key descriptor: {}",
2573 desc_str
2574 );
2575 }
2576
2577 let threshold_tests = vec![
2579 (
2581 format!(
2582 "wsh(thresh(2,c:pk_k({}),sc:pk_k({}),sc:pk_k({})))",
2583 single_keys[0], mainnet_xpubs[0], testnet_tpubs[0]
2584 ),
2585 XKeyNetwork::Mixed,
2586 ),
2587 (
2589 format!("wsh(or_d(pk({}),pk({})))", mainnet_xpubs[0], testnet_tpubs[0]),
2590 XKeyNetwork::Mixed,
2591 ),
2592 (
2594 format!("wsh(and_v(v:pk({}),pk({})))", mainnet_xpubs[0], mainnet_xpubs[1]),
2595 XKeyNetwork::Single(NetworkKind::Main),
2596 ),
2597 (
2599 format!(
2600 "wsh(thresh(3,c:pk_k({}),sc:pk_k({}),sc:pk_k({}),sc:pk_k({})))",
2601 testnet_tpubs[0], testnet_tpubs[1], testnet_tpubs[2], testnet_tpubs[3]
2602 ),
2603 XKeyNetwork::Single(NetworkKind::Test),
2604 ),
2605 ];
2606
2607 for (desc_str, expected) in threshold_tests {
2608 let desc = Descriptor::<DescriptorPublicKey>::from_str(&desc_str).unwrap();
2609 assert_eq!(
2610 desc.xkey_network(),
2611 expected,
2612 "Failed for threshold descriptor: {}",
2613 desc_str
2614 );
2615 }
2616
2617 let complex_tests = vec![
2619 (format!("tr({},pk({}))", mainnet_xpubs[0], testnet_tpubs[0]), XKeyNetwork::Mixed),
2621 (format!("tr({},pk({}))", mainnet_xpubs[0], mainnet_xpubs[1]), XKeyNetwork::Single(NetworkKind::Main)),
2623 (format!("wsh(andor(pk({}),sha256(1111111111111111111111111111111111111111111111111111111111111111),and_v(v:pkh({}),older(144))))", mainnet_xpubs[0], testnet_tpubs[0]), XKeyNetwork::Mixed),
2625 (format!("wsh(or_d(multi(2,{},{}),and_v(v:pk({}),older(1000))))", testnet_tpubs[0], testnet_tpubs[1], testnet_tpubs[2]), XKeyNetwork::Single(NetworkKind::Test)),
2627 (format!("wsh(thresh(3,c:pk_k({}),sc:pk_k({}),sc:pk_k({}),sc:pk_k({})))", single_keys[0], single_keys[1], single_keys[2], single_keys[3]), XKeyNetwork::NoXKeys),
2629 (format!("wsh(or_d(multi(2,{},{}),and_v(v:pk({}),older(1000))))", mainnet_xpubs[0], mainnet_xpubs[1], mainnet_xpubs[2]), XKeyNetwork::Single(NetworkKind::Main)),
2631 ];
2632
2633 for (desc_str, expected) in complex_tests {
2634 let desc = Descriptor::<DescriptorPublicKey>::from_str(&desc_str).unwrap();
2635 assert_eq!(
2636 desc.xkey_network(),
2637 expected,
2638 "Failed for complex descriptor: {}",
2639 desc_str
2640 );
2641 }
2642 }
2643
2644 #[test]
2645 fn test_definite_descriptor_key_xkey_network() {
2646 use core::str::FromStr;
2647
2648 use bitcoin::NetworkKind;
2649
2650 use crate::descriptor::{DefiniteDescriptorKey, XKeyNetwork};
2651
2652 let (mainnet_xpubs, testnet_tpubs, single_keys) = test_keys();
2653
2654 let definite_key_tests = vec![
2656 (format!("wpkh({})", mainnet_xpubs[0]), XKeyNetwork::Single(NetworkKind::Main)),
2658 (format!("wpkh({})", testnet_tpubs[0]), XKeyNetwork::Single(NetworkKind::Test)),
2659 (format!("wpkh({})", single_keys[0]), XKeyNetwork::NoXKeys),
2660 (
2662 format!("wsh(multi(2,{},{}))", mainnet_xpubs[0], testnet_tpubs[0]),
2663 XKeyNetwork::Mixed,
2664 ),
2665 (
2666 format!("wsh(multi(2,{}/0,{}/1))", testnet_tpubs[0], testnet_tpubs[1]),
2667 XKeyNetwork::Single(NetworkKind::Test),
2668 ),
2669 (
2670 format!("wsh(multi(2,{}/0,{}/1))", mainnet_xpubs[0], mainnet_xpubs[1]),
2671 XKeyNetwork::Single(NetworkKind::Main),
2672 ),
2673 (
2675 format!(
2676 "wsh(sortedmulti(2,{}/0,{}/1,{}))",
2677 mainnet_xpubs[0], testnet_tpubs[0], single_keys[0]
2678 ),
2679 XKeyNetwork::Mixed,
2680 ),
2681 (format!("tr({})", mainnet_xpubs[0]), XKeyNetwork::Single(NetworkKind::Main)),
2683 (
2684 format!("tr({},pk({}/0))", mainnet_xpubs[0], testnet_tpubs[0]),
2685 XKeyNetwork::Mixed,
2686 ),
2687 ];
2688
2689 for (desc_str, expected) in definite_key_tests {
2690 let desc = Descriptor::<DefiniteDescriptorKey>::from_str(&desc_str).unwrap();
2691 assert_eq!(
2692 desc.xkey_network(),
2693 expected,
2694 "Failed for DefiniteDescriptorKey: {}",
2695 desc_str
2696 );
2697 }
2698 }
2699}