1use core::{fmt, str};
7#[cfg(feature = "std")]
8use std::error;
9
10use bitcoin::absolute;
11#[cfg(feature = "compiler")]
12use {
13 crate::descriptor::TapTree,
14 crate::miniscript::ScriptContext,
15 crate::policy::compiler::CompilerError,
16 crate::policy::compiler::OrdF64,
17 crate::policy::{compiler, Concrete, Liftable, Semantic},
18 crate::Descriptor,
19 crate::Miniscript,
20 crate::Tap,
21 core::cmp::Reverse,
22};
23
24use super::ENTAILMENT_MAX_TERMINALS;
25use crate::expression::{self, FromTree};
26use crate::iter::{Tree, TreeLike};
27use crate::miniscript::types::extra_props::TimelockInfo;
28use crate::prelude::*;
29use crate::sync::Arc;
30#[cfg(all(doc, not(feature = "compiler")))]
31use crate::Descriptor;
32use crate::{
33 errstr, AbsLockTime, Error, ForEachKey, FromStrKey, MiniscriptKey, RelLockTime, Threshold,
34 Translator,
35};
36
37#[cfg(feature = "compiler")]
39const MAX_COMPILATION_LEAVES: usize = 1024;
40
41#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
48pub enum Policy<Pk: MiniscriptKey> {
49 Unsatisfiable,
51 Trivial,
53 Key(Pk),
55 After(AbsLockTime),
57 Older(RelLockTime),
59 Sha256(Pk::Sha256),
61 Hash256(Pk::Hash256),
63 Ripemd160(Pk::Ripemd160),
65 Hash160(Pk::Hash160),
67 And(Vec<Arc<Policy<Pk>>>),
69 Or(Vec<(usize, Arc<Policy<Pk>>)>),
72 Thresh(Threshold<Arc<Policy<Pk>>, 0>),
74}
75
76#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
78pub enum PolicyError {
79 NonBinaryArgAnd,
81 NonBinaryArgOr,
83 InsufficientArgsforAnd,
85 InsufficientArgsforOr,
87 EntailmentMaxTerminals,
89 HeightTimelockCombination,
91 DuplicatePubKeys,
93}
94
95pub enum DescriptorCtx<Pk> {
97 Bare,
99 Sh,
101 Wsh,
103 ShWsh,
105 Tr(Option<Pk>),
108}
109
110impl fmt::Display for PolicyError {
111 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
112 match *self {
113 PolicyError::NonBinaryArgAnd => {
114 f.write_str("And policy fragment must take 2 arguments")
115 }
116 PolicyError::NonBinaryArgOr => f.write_str("Or policy fragment must take 2 arguments"),
117 PolicyError::InsufficientArgsforAnd => {
118 f.write_str("Semantic Policy 'And' fragment must have at least 2 args ")
119 }
120 PolicyError::InsufficientArgsforOr => {
121 f.write_str("Semantic Policy 'Or' fragment must have at least 2 args ")
122 }
123 PolicyError::EntailmentMaxTerminals => {
124 write!(f, "Policy entailment only supports {} terminals", ENTAILMENT_MAX_TERMINALS)
125 }
126 PolicyError::HeightTimelockCombination => {
127 f.write_str("Cannot lift policies that have a heightlock and timelock combination")
128 }
129 PolicyError::DuplicatePubKeys => f.write_str("Policy contains duplicate keys"),
130 }
131 }
132}
133
134#[cfg(feature = "std")]
135impl error::Error for PolicyError {
136 fn cause(&self) -> Option<&dyn error::Error> {
137 use self::PolicyError::*;
138
139 match self {
140 NonBinaryArgAnd
141 | NonBinaryArgOr
142 | InsufficientArgsforAnd
143 | InsufficientArgsforOr
144 | EntailmentMaxTerminals
145 | HeightTimelockCombination
146 | DuplicatePubKeys => None,
147 }
148 }
149}
150
151impl<Pk: MiniscriptKey> Policy<Pk> {
152 #[cfg(feature = "compiler")]
175 fn to_tapleaf_prob_vec(&self, prob: f64) -> Vec<(f64, Policy<Pk>)> {
176 match self {
177 Policy::Or(ref subs) => {
178 let total_odds: usize = subs.iter().map(|(ref k, _)| k).sum();
179 subs.iter()
180 .flat_map(|(k, ref policy)| {
181 policy.to_tapleaf_prob_vec(prob * *k as f64 / total_odds as f64)
182 })
183 .collect::<Vec<_>>()
184 }
185 Policy::Thresh(ref thresh) if thresh.is_or() => {
186 let total_odds = thresh.n();
187 thresh
188 .iter()
189 .flat_map(|policy| policy.to_tapleaf_prob_vec(prob / total_odds as f64))
190 .collect::<Vec<_>>()
191 }
192 x => vec![(prob, x.clone())],
193 }
194 }
195
196 #[cfg(feature = "compiler")]
198 fn extract_key(self, unspendable_key: Option<Pk>) -> Result<(Pk, Policy<Pk>), Error> {
199 let mut internal_key: Option<Pk> = None;
200 {
201 let mut prob = 0.;
202 let semantic_policy = self.lift()?;
203 let concrete_keys = self.keys();
204 let key_prob_map: BTreeMap<_, _> = self
205 .to_tapleaf_prob_vec(1.0)
206 .into_iter()
207 .filter(|(_, ref pol)| matches!(pol, Concrete::Key(..)))
208 .map(|(prob, key)| (key, prob))
209 .collect();
210
211 for key in concrete_keys.into_iter() {
212 if semantic_policy
213 .clone()
214 .satisfy_constraint(&Semantic::Key(key.clone()), true)
215 == Semantic::Trivial
216 {
217 match key_prob_map.get(&Concrete::Key(key.clone())) {
218 Some(val) => {
219 if *val > prob {
220 prob = *val;
221 internal_key = Some(key.clone());
222 }
223 }
224 None => return Err(errstr("Key should have existed in the BTreeMap!")),
225 }
226 }
227 }
228 }
229 match (internal_key, unspendable_key) {
230 (Some(ref key), _) => Ok((key.clone(), self.translate_unsatisfiable_pk(key))),
231 (_, Some(key)) => Ok((key, self)),
232 _ => Err(errstr("No viable internal key found.")),
233 }
234 }
235
236 #[cfg(feature = "compiler")]
254 pub fn compile_tr(&self, unspendable_key: Option<Pk>) -> Result<Descriptor<Pk>, Error> {
255 self.is_valid()?; match self.is_safe_nonmalleable() {
257 (false, _) => Err(Error::from(CompilerError::TopLevelNonSafe)),
258 (_, false) => Err(Error::from(CompilerError::ImpossibleNonMalleableCompilation)),
259 _ => {
260 let (internal_key, policy) = self.clone().extract_key(unspendable_key)?;
261 policy.check_num_tapleaves()?;
262 let tree = Descriptor::new_tr(
263 internal_key,
264 match policy {
265 Policy::Trivial => None,
266 policy => {
267 let vec_policies: Vec<_> = policy.to_tapleaf_prob_vec(1.0);
268 let mut leaf_compilations: Vec<(OrdF64, Miniscript<Pk, Tap>)> = vec![];
269 for (prob, pol) in vec_policies {
270 if pol == Policy::Unsatisfiable {
272 continue;
273 }
274 let compilation = compiler::best_compilation::<Pk, Tap>(&pol)?;
275 compilation.sanity_check()?;
276 leaf_compilations.push((OrdF64(prob), compilation));
277 }
278 let tap_tree = with_huffman_tree::<Pk>(leaf_compilations)?;
279 Some(tap_tree)
280 }
281 },
282 )?;
283 Ok(tree)
284 }
285 }
286 }
287
288 #[cfg(feature = "compiler")]
307 pub fn compile_tr_private_experimental(
308 &self,
309 unspendable_key: Option<Pk>,
310 ) -> Result<Descriptor<Pk>, Error> {
311 self.is_valid()?; match self.is_safe_nonmalleable() {
313 (false, _) => Err(Error::from(CompilerError::TopLevelNonSafe)),
314 (_, false) => Err(Error::from(CompilerError::ImpossibleNonMalleableCompilation)),
315 _ => {
316 let (internal_key, policy) = self.clone().extract_key(unspendable_key)?;
317 let tree = Descriptor::new_tr(
318 internal_key,
319 match policy {
320 Policy::Trivial => None,
321 policy => {
322 let leaf_compilations: Vec<_> = policy
323 .enumerate_policy_tree(1.0)
324 .into_iter()
325 .filter(|x| x.1 != Arc::new(Policy::Unsatisfiable))
326 .map(|(prob, pol)| {
327 (
328 OrdF64(prob),
329 compiler::best_compilation(pol.as_ref()).unwrap(),
330 )
331 })
332 .collect();
333 let tap_tree = with_huffman_tree::<Pk>(leaf_compilations).unwrap();
334 Some(tap_tree)
335 }
336 },
337 )?;
338 Ok(tree)
339 }
340 }
341 }
342
343 #[cfg(feature = "compiler")]
354 pub fn compile_to_descriptor<Ctx: ScriptContext>(
355 &self,
356 desc_ctx: DescriptorCtx<Pk>,
357 ) -> Result<Descriptor<Pk>, Error> {
358 self.is_valid()?;
359 match self.is_safe_nonmalleable() {
360 (false, _) => Err(Error::from(CompilerError::TopLevelNonSafe)),
361 (_, false) => Err(Error::from(CompilerError::ImpossibleNonMalleableCompilation)),
362 _ => match desc_ctx {
363 DescriptorCtx::Bare => Descriptor::new_bare(compiler::best_compilation(self)?),
364 DescriptorCtx::Sh => Descriptor::new_sh(compiler::best_compilation(self)?),
365 DescriptorCtx::Wsh => Descriptor::new_wsh(compiler::best_compilation(self)?),
366 DescriptorCtx::ShWsh => Descriptor::new_sh_wsh(compiler::best_compilation(self)?),
367 DescriptorCtx::Tr(unspendable_key) => self.compile_tr(unspendable_key),
368 },
369 }
370 }
371
372 #[cfg(feature = "compiler")]
380 pub fn compile<Ctx: ScriptContext>(&self) -> Result<Miniscript<Pk, Ctx>, CompilerError> {
381 self.is_valid()?;
382 match self.is_safe_nonmalleable() {
383 (false, _) => Err(CompilerError::TopLevelNonSafe),
384 (_, false) => Err(CompilerError::ImpossibleNonMalleableCompilation),
385 _ => compiler::best_compilation(self),
386 }
387 }
388}
389
390#[cfg(feature = "compiler")]
391impl<Pk: MiniscriptKey> Policy<Pk> {
392 #[cfg(feature = "compiler")]
398 fn enumerate_pol(&self, prob: f64) -> Vec<(f64, Arc<Self>)> {
399 match self {
400 Policy::Or(subs) => {
401 let total_odds = subs.iter().fold(0, |acc, x| acc + x.0);
402 subs.iter()
403 .map(|(odds, pol)| (prob * *odds as f64 / total_odds as f64, pol.clone()))
404 .collect::<Vec<_>>()
405 }
406 Policy::Thresh(ref thresh) if thresh.is_or() => {
407 let total_odds = thresh.n();
408 thresh
409 .iter()
410 .map(|pol| (prob / total_odds as f64, pol.clone()))
411 .collect::<Vec<_>>()
412 }
413 Policy::Thresh(ref thresh) if !thresh.is_and() => generate_combination(thresh, prob),
414 pol => vec![(prob, Arc::new(pol.clone()))],
415 }
416 }
417
418 #[cfg(feature = "compiler")]
425 fn enumerate_policy_tree(self, prob: f64) -> Vec<(f64, Arc<Self>)> {
426 let mut tapleaf_prob_vec = BTreeSet::<(Reverse<OrdF64>, Arc<Self>)>::new();
427 let mut pol_prob_map = BTreeMap::<Arc<Self>, OrdF64>::new();
432
433 let arc_self = Arc::new(self);
434 tapleaf_prob_vec.insert((Reverse(OrdF64(prob)), Arc::clone(&arc_self)));
435 pol_prob_map.insert(Arc::clone(&arc_self), OrdF64(prob));
436
437 let mut prev_len = 0usize;
441 let mut enum_len = tapleaf_prob_vec.len();
444
445 let mut ret: Vec<(f64, Arc<Self>)> = vec![];
446
447 'outer: loop {
449 let mut prob: Reverse<OrdF64> = Reverse(OrdF64(0.0));
451 let mut curr_policy: Arc<Self> = Arc::new(Policy::Unsatisfiable);
452 let mut curr_pol_replace_vec: Vec<(f64, Arc<Self>)> = vec![];
453 let mut no_more_enum = false;
454
455 let mut to_del: Vec<(f64, Arc<Self>)> = vec![];
458 'inner: for (i, (p, pol)) in tapleaf_prob_vec.iter().enumerate() {
459 curr_pol_replace_vec = pol.enumerate_pol(p.0 .0);
460 enum_len += curr_pol_replace_vec.len() - 1; assert!(prev_len <= enum_len);
462
463 if prev_len < enum_len {
464 prob = *p;
466 curr_policy = Arc::clone(pol);
467 break 'inner;
468 } else if i == tapleaf_prob_vec.len() - 1 {
469 no_more_enum = true;
472 } else {
473 to_del.push((p.0 .0, Arc::clone(pol)));
477 }
478 }
479
480 if enum_len > MAX_COMPILATION_LEAVES || no_more_enum {
482 for (p, pol) in tapleaf_prob_vec.into_iter() {
483 ret.push((p.0 .0, pol));
484 }
485 break 'outer;
486 }
487
488 assert!(tapleaf_prob_vec.remove(&(prob, curr_policy.clone())));
493
494 for (p, pol) in to_del {
496 assert!(tapleaf_prob_vec.remove(&(Reverse(OrdF64(p)), pol.clone())));
497 ret.push((p, pol.clone()));
498 }
499
500 for (p, policy) in curr_pol_replace_vec {
502 match pol_prob_map.get(&policy) {
503 Some(prev_prob) => {
504 assert!(tapleaf_prob_vec.remove(&(Reverse(*prev_prob), policy.clone())));
505 tapleaf_prob_vec.insert((Reverse(OrdF64(prev_prob.0 + p)), policy.clone()));
506 pol_prob_map.insert(policy.clone(), OrdF64(prev_prob.0 + p));
507 }
508 None => {
509 tapleaf_prob_vec.insert((Reverse(OrdF64(p)), policy.clone()));
510 pol_prob_map.insert(policy.clone(), OrdF64(p));
511 }
512 }
513 }
514 prev_len = enum_len;
516 }
517
518 ret
519 }
520}
521
522impl<Pk: MiniscriptKey> ForEachKey<Pk> for Policy<Pk> {
523 fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
524 self.pre_order_iter().all(|policy| match policy {
525 Policy::Key(ref pk) => pred(pk),
526 _ => true,
527 })
528 }
529}
530
531impl<Pk: MiniscriptKey> Policy<Pk> {
532 pub fn translate_pk<Q, E, T>(&self, t: &mut T) -> Result<Policy<Q>, E>
536 where
537 T: Translator<Pk, Q, E>,
538 Q: MiniscriptKey,
539 {
540 use Policy::*;
541
542 let mut translated = vec![];
543 for data in self.post_order_iter() {
544 let child_n = |n| Arc::clone(&translated[data.child_indices[n]]);
545
546 let new_policy = match data.node {
547 Unsatisfiable => Unsatisfiable,
548 Trivial => Trivial,
549 Key(ref pk) => t.pk(pk).map(Key)?,
550 Sha256(ref h) => t.sha256(h).map(Sha256)?,
551 Hash256(ref h) => t.hash256(h).map(Hash256)?,
552 Ripemd160(ref h) => t.ripemd160(h).map(Ripemd160)?,
553 Hash160(ref h) => t.hash160(h).map(Hash160)?,
554 Older(ref n) => Older(*n),
555 After(ref n) => After(*n),
556 And(ref subs) => And((0..subs.len()).map(child_n).collect()),
557 Or(ref subs) => Or(subs
558 .iter()
559 .enumerate()
560 .map(|(i, (prob, _))| (*prob, child_n(i)))
561 .collect()),
562 Thresh(ref thresh) => {
563 Thresh(thresh.map_from_post_order_iter(&data.child_indices, &translated))
564 }
565 };
566 translated.push(Arc::new(new_policy));
567 }
568 let root_node = translated.pop().unwrap();
570 Ok(Arc::try_unwrap(root_node).unwrap())
572 }
573
574 pub fn translate_unsatisfiable_pk(self, key: &Pk) -> Policy<Pk> {
576 use Policy::*;
577
578 let mut translated = vec![];
579 for data in Arc::new(self).post_order_iter() {
580 let child_n = |n| Arc::clone(&translated[data.child_indices[n]]);
581
582 let new_policy = match data.node.as_ref() {
583 Policy::Key(ref k) if k.clone() == *key => Some(Policy::Unsatisfiable),
584 And(ref subs) => Some(And((0..subs.len()).map(child_n).collect())),
585 Or(ref subs) => Some(Or(subs
586 .iter()
587 .enumerate()
588 .map(|(i, (prob, _))| (*prob, child_n(i)))
589 .collect())),
590 Thresh(ref thresh) => {
591 Some(Thresh(thresh.map_from_post_order_iter(&data.child_indices, &translated)))
592 }
593 _ => None,
594 };
595 match new_policy {
596 Some(new_policy) => translated.push(Arc::new(new_policy)),
597 None => translated.push(Arc::clone(&data.node)),
598 }
599 }
600 let root_node = translated.pop().unwrap();
602 Arc::try_unwrap(root_node).unwrap()
604 }
605
606 pub fn keys(&self) -> Vec<&Pk> {
608 self.pre_order_iter()
609 .filter_map(|policy| match policy {
610 Policy::Key(ref pk) => Some(pk),
611 _ => None,
612 })
613 .collect()
614 }
615
616 #[cfg(feature = "compiler")]
619 fn num_tap_leaves(&self) -> usize {
620 use Policy::*;
621
622 let mut nums = vec![];
623 for data in Arc::new(self).post_order_iter() {
624 let num_for_child_n = |n| nums[data.child_indices[n]];
625
626 let num = match data.node {
627 Or(subs) => (0..subs.len()).map(num_for_child_n).sum(),
628 Thresh(thresh) if thresh.is_or() => (0..thresh.n()).map(num_for_child_n).sum(),
629 _ => 1,
630 };
631 nums.push(num);
632 }
633 nums.pop().unwrap()
635 }
636
637 #[cfg(feature = "compiler")]
639 fn check_num_tapleaves(&self) -> Result<(), Error> {
640 if self.num_tap_leaves() > MAX_COMPILATION_LEAVES {
641 return Err(errstr("Too many Tapleaves"));
642 }
643 Ok(())
644 }
645
646 pub fn check_duplicate_keys(&self) -> Result<(), PolicyError> {
648 let pks = self.keys();
649 let pks_len = pks.len();
650 let unique_pks_len = pks.into_iter().collect::<BTreeSet<_>>().len();
651
652 if pks_len > unique_pks_len {
653 Err(PolicyError::DuplicatePubKeys)
654 } else {
655 Ok(())
656 }
657 }
658
659 pub fn check_timelocks(&self) -> Result<(), PolicyError> {
667 let aggregated_timelock_info = self.timelock_info();
668 if aggregated_timelock_info.contains_combination {
669 Err(PolicyError::HeightTimelockCombination)
670 } else {
671 Ok(())
672 }
673 }
674
675 fn timelock_info(&self) -> TimelockInfo {
682 use Policy::*;
683
684 let mut infos = vec![];
685 for data in Arc::new(self).post_order_iter() {
686 let info_for_child_n = |n| infos[data.child_indices[n]];
687
688 let info = match data.node {
689 Policy::After(ref t) => TimelockInfo {
690 csv_with_height: false,
691 csv_with_time: false,
692 cltv_with_height: absolute::LockTime::from(*t).is_block_height(),
693 cltv_with_time: absolute::LockTime::from(*t).is_block_time(),
694 contains_combination: false,
695 },
696 Policy::Older(ref t) => TimelockInfo {
697 csv_with_height: t.is_height_locked(),
698 csv_with_time: t.is_time_locked(),
699 cltv_with_height: false,
700 cltv_with_time: false,
701 contains_combination: false,
702 },
703 And(ref subs) => {
704 let iter = (0..subs.len()).map(info_for_child_n);
705 TimelockInfo::combine_threshold(subs.len(), iter)
706 }
707 Or(ref subs) => {
708 let iter = (0..subs.len()).map(info_for_child_n);
709 TimelockInfo::combine_threshold(1, iter)
710 }
711 Thresh(ref thresh) => {
712 let iter = (0..thresh.n()).map(info_for_child_n);
713 TimelockInfo::combine_threshold(thresh.k(), iter)
714 }
715 _ => TimelockInfo::default(),
716 };
717 infos.push(info);
718 }
719 infos.pop().unwrap()
721 }
722
723 pub fn is_valid(&self) -> Result<(), PolicyError> {
728 use Policy::*;
729
730 self.check_timelocks()?;
731 self.check_duplicate_keys()?;
732
733 for policy in self.pre_order_iter() {
734 match *policy {
735 And(ref subs) => {
736 if subs.len() != 2 {
737 return Err(PolicyError::NonBinaryArgAnd);
738 }
739 }
740 Or(ref subs) => {
741 if subs.len() != 2 {
742 return Err(PolicyError::NonBinaryArgOr);
743 }
744 }
745 _ => {}
746 }
747 }
748 Ok(())
749 }
750
751 pub fn is_safe_nonmalleable(&self) -> (bool, bool) {
759 use Policy::*;
760
761 let mut acc = vec![];
762 for data in Arc::new(self).post_order_iter() {
763 let acc_for_child_n = |n| acc[data.child_indices[n]];
764
765 let new = match data.node {
766 Unsatisfiable | Trivial | Key(_) => (true, true),
767 Sha256(_) | Hash256(_) | Ripemd160(_) | Hash160(_) | After(_) | Older(_) => {
768 (false, true)
769 }
770 And(ref subs) => {
771 let (atleast_one_safe, all_non_mall) = (0..subs.len())
772 .map(acc_for_child_n)
773 .fold((false, true), |acc, x: (bool, bool)| (acc.0 || x.0, acc.1 && x.1));
774 (atleast_one_safe, all_non_mall)
775 }
776 Or(ref subs) => {
777 let (all_safe, atleast_one_safe, all_non_mall) = (0..subs.len())
778 .map(acc_for_child_n)
779 .fold((true, false, true), |acc, x| {
780 (acc.0 && x.0, acc.1 || x.0, acc.2 && x.1)
781 });
782 (all_safe, atleast_one_safe && all_non_mall)
783 }
784 Thresh(ref thresh) => {
785 let (safe_count, non_mall_count) = (0..thresh.n()).map(acc_for_child_n).fold(
786 (0, 0),
787 |(safe_count, non_mall_count), (safe, non_mall)| {
788 (safe_count + safe as usize, non_mall_count + non_mall as usize)
789 },
790 );
791 (
792 safe_count >= (thresh.n() - thresh.k() + 1),
793 non_mall_count == thresh.n() && safe_count >= (thresh.n() - thresh.k()),
794 )
795 }
796 };
797 acc.push(new);
798 }
799 acc.pop().unwrap()
801 }
802}
803
804impl<Pk: MiniscriptKey> fmt::Debug for Policy<Pk> {
805 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
806 match *self {
807 Policy::Unsatisfiable => f.write_str("UNSATISFIABLE()"),
808 Policy::Trivial => f.write_str("TRIVIAL()"),
809 Policy::Key(ref pk) => write!(f, "pk({:?})", pk),
810 Policy::After(n) => write!(f, "after({})", n),
811 Policy::Older(n) => write!(f, "older({})", n),
812 Policy::Sha256(ref h) => write!(f, "sha256({})", h),
813 Policy::Hash256(ref h) => write!(f, "hash256({})", h),
814 Policy::Ripemd160(ref h) => write!(f, "ripemd160({})", h),
815 Policy::Hash160(ref h) => write!(f, "hash160({})", h),
816 Policy::And(ref subs) => {
817 f.write_str("and(")?;
818 if !subs.is_empty() {
819 write!(f, "{:?}", subs[0])?;
820 for sub in &subs[1..] {
821 write!(f, ",{:?}", sub)?;
822 }
823 }
824 f.write_str(")")
825 }
826 Policy::Or(ref subs) => {
827 f.write_str("or(")?;
828 if !subs.is_empty() {
829 write!(f, "{}@{:?}", subs[0].0, subs[0].1)?;
830 for sub in &subs[1..] {
831 write!(f, ",{}@{:?}", sub.0, sub.1)?;
832 }
833 }
834 f.write_str(")")
835 }
836 Policy::Thresh(ref thresh) => fmt::Debug::fmt(&thresh.debug("thresh", true), f),
837 }
838 }
839}
840
841impl<Pk: MiniscriptKey> fmt::Display for Policy<Pk> {
842 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
843 match *self {
844 Policy::Unsatisfiable => f.write_str("UNSATISFIABLE"),
845 Policy::Trivial => f.write_str("TRIVIAL"),
846 Policy::Key(ref pk) => write!(f, "pk({})", pk),
847 Policy::After(n) => write!(f, "after({})", n),
848 Policy::Older(n) => write!(f, "older({})", n),
849 Policy::Sha256(ref h) => write!(f, "sha256({})", h),
850 Policy::Hash256(ref h) => write!(f, "hash256({})", h),
851 Policy::Ripemd160(ref h) => write!(f, "ripemd160({})", h),
852 Policy::Hash160(ref h) => write!(f, "hash160({})", h),
853 Policy::And(ref subs) => {
854 f.write_str("and(")?;
855 if !subs.is_empty() {
856 write!(f, "{}", subs[0])?;
857 for sub in &subs[1..] {
858 write!(f, ",{}", sub)?;
859 }
860 }
861 f.write_str(")")
862 }
863 Policy::Or(ref subs) => {
864 f.write_str("or(")?;
865 if !subs.is_empty() {
866 write!(f, "{}@{}", subs[0].0, subs[0].1)?;
867 for sub in &subs[1..] {
868 write!(f, ",{}@{}", sub.0, sub.1)?;
869 }
870 }
871 f.write_str(")")
872 }
873 Policy::Thresh(ref thresh) => fmt::Display::fmt(&thresh.display("thresh", true), f),
874 }
875 }
876}
877
878impl<Pk: FromStrKey> str::FromStr for Policy<Pk> {
879 type Err = Error;
880 fn from_str(s: &str) -> Result<Policy<Pk>, Error> {
881 expression::check_valid_chars(s)?;
882
883 let tree = expression::Tree::from_str(s)?;
884 let policy: Policy<Pk> = FromTree::from_tree(&tree)?;
885 policy.check_timelocks()?;
886 Ok(policy)
887 }
888}
889
890serde_string_impl_pk!(Policy, "a miniscript concrete policy");
891
892impl<Pk: FromStrKey> Policy<Pk> {
893 fn from_tree_prob(
896 top: &expression::Tree,
897 allow_prob: bool,
898 ) -> Result<(usize, Policy<Pk>), Error> {
899 let frag_prob;
900 let frag_name;
901 let mut name_split = top.name.split('@');
902 match (name_split.next(), name_split.next(), name_split.next()) {
903 (None, _, _) => {
904 frag_prob = 1;
905 frag_name = "";
906 }
907 (Some(name), None, _) => {
908 frag_prob = 1;
909 frag_name = name;
910 }
911 (Some(prob), Some(name), None) => {
912 if !allow_prob {
913 return Err(Error::AtOutsideOr(top.name.to_owned()));
914 }
915 frag_prob = expression::parse_num(prob)? as usize;
916 frag_name = name;
917 }
918 (Some(_), Some(_), Some(_)) => {
919 return Err(Error::MultiColon(top.name.to_owned()));
920 }
921 }
922 match (frag_name, top.args.len() as u32) {
923 ("UNSATISFIABLE", 0) => Ok(Policy::Unsatisfiable),
924 ("TRIVIAL", 0) => Ok(Policy::Trivial),
925 ("pk", 1) => expression::terminal(&top.args[0], |pk| Pk::from_str(pk).map(Policy::Key)),
926 ("after", 1) => expression::terminal(&top.args[0], |x| {
927 expression::parse_num(x)
928 .and_then(|x| AbsLockTime::from_consensus(x).map_err(Error::AbsoluteLockTime))
929 .map(Policy::After)
930 }),
931 ("older", 1) => expression::terminal(&top.args[0], |x| {
932 expression::parse_num(x)
933 .and_then(|x| RelLockTime::from_consensus(x).map_err(Error::RelativeLockTime))
934 .map(Policy::Older)
935 }),
936 ("sha256", 1) => expression::terminal(&top.args[0], |x| {
937 <Pk::Sha256 as core::str::FromStr>::from_str(x).map(Policy::Sha256)
938 }),
939 ("hash256", 1) => expression::terminal(&top.args[0], |x| {
940 <Pk::Hash256 as core::str::FromStr>::from_str(x).map(Policy::Hash256)
941 }),
942 ("ripemd160", 1) => expression::terminal(&top.args[0], |x| {
943 <Pk::Ripemd160 as core::str::FromStr>::from_str(x).map(Policy::Ripemd160)
944 }),
945 ("hash160", 1) => expression::terminal(&top.args[0], |x| {
946 <Pk::Hash160 as core::str::FromStr>::from_str(x).map(Policy::Hash160)
947 }),
948 ("and", _) => {
949 if top.args.len() != 2 {
950 return Err(Error::PolicyError(PolicyError::NonBinaryArgAnd));
951 }
952 let mut subs = Vec::with_capacity(top.args.len());
953 for arg in &top.args {
954 subs.push(Arc::new(Policy::from_tree(arg)?));
955 }
956 Ok(Policy::And(subs))
957 }
958 ("or", _) => {
959 if top.args.len() != 2 {
960 return Err(Error::PolicyError(PolicyError::NonBinaryArgOr));
961 }
962 let mut subs = Vec::with_capacity(top.args.len());
963 for arg in &top.args {
964 subs.push(Policy::from_tree_prob(arg, true)?);
965 }
966 Ok(Policy::Or(
967 subs.into_iter()
968 .map(|(prob, sub)| (prob, Arc::new(sub)))
969 .collect(),
970 ))
971 }
972 ("thresh", _) => top
973 .to_null_threshold()
974 .map_err(Error::ParseThreshold)?
975 .translate_by_index(|i| Policy::from_tree(&top.args[1 + i]).map(Arc::new))
976 .map(Policy::Thresh),
977 _ => Err(errstr(top.name)),
978 }
979 .map(|res| (frag_prob, res))
980 }
981}
982
983impl<Pk: FromStrKey> expression::FromTree for Policy<Pk> {
984 fn from_tree(top: &expression::Tree) -> Result<Policy<Pk>, Error> {
985 Policy::from_tree_prob(top, false).map(|(_, result)| result)
986 }
987}
988
989#[cfg(feature = "compiler")]
991fn with_huffman_tree<Pk: MiniscriptKey>(
992 ms: Vec<(OrdF64, Miniscript<Pk, Tap>)>,
993) -> Result<TapTree<Pk>, Error> {
994 let mut node_weights = BinaryHeap::<(Reverse<OrdF64>, TapTree<Pk>)>::new();
995 for (prob, script) in ms {
996 node_weights.push((Reverse(prob), TapTree::Leaf(Arc::new(script))));
997 }
998 if node_weights.is_empty() {
999 return Err(errstr("Empty Miniscript compilation"));
1000 }
1001 while node_weights.len() > 1 {
1002 let (p1, s1) = node_weights.pop().expect("len must atleast be two");
1003 let (p2, s2) = node_weights.pop().expect("len must atleast be two");
1004
1005 let p = (p1.0).0 + (p2.0).0;
1006 node_weights.push((Reverse(OrdF64(p)), TapTree::combine(s1, s2)));
1007 }
1008
1009 debug_assert!(node_weights.len() == 1);
1010 let node = node_weights
1011 .pop()
1012 .expect("huffman tree algorithm is broken")
1013 .1;
1014 Ok(node)
1015}
1016
1017#[cfg(feature = "compiler")]
1025fn generate_combination<Pk: MiniscriptKey>(
1026 thresh: &Threshold<Arc<Policy<Pk>>, 0>,
1027 prob: f64,
1028) -> Vec<(f64, Arc<Policy<Pk>>)> {
1029 debug_assert!(thresh.k() < thresh.n());
1030
1031 let prob_over_n = prob / thresh.n() as f64;
1032 let mut ret: Vec<(f64, Arc<Policy<Pk>>)> = vec![];
1033 for i in 0..thresh.n() {
1034 let thresh_less_1 = Threshold::from_iter(
1035 thresh.k(),
1036 thresh
1037 .iter()
1038 .enumerate()
1039 .filter_map(|(j, sub)| if j != i { Some(Arc::clone(sub)) } else { None }),
1040 )
1041 .expect("k is strictly less than n, so (k, n-1) is a valid threshold");
1042 ret.push((prob_over_n, Arc::new(Policy::Thresh(thresh_less_1))));
1043 }
1044 ret
1045}
1046
1047impl<Pk: MiniscriptKey> TreeLike for &'_ Policy<Pk> {
1048 fn as_node(&self) -> Tree<Self> {
1049 use Policy::*;
1050
1051 match *self {
1052 Unsatisfiable | Trivial | Key(_) | After(_) | Older(_) | Sha256(_) | Hash256(_)
1053 | Ripemd160(_) | Hash160(_) => Tree::Nullary,
1054 And(ref subs) => Tree::Nary(subs.iter().map(Arc::as_ref).collect()),
1055 Or(ref v) => Tree::Nary(v.iter().map(|(_, p)| p.as_ref()).collect()),
1056 Thresh(ref thresh) => Tree::Nary(thresh.iter().map(Arc::as_ref).collect()),
1057 }
1058 }
1059}
1060
1061impl<Pk: MiniscriptKey> TreeLike for Arc<Policy<Pk>> {
1062 fn as_node(&self) -> Tree<Self> {
1063 use Policy::*;
1064
1065 match self.as_ref() {
1066 Unsatisfiable | Trivial | Key(_) | After(_) | Older(_) | Sha256(_) | Hash256(_)
1067 | Ripemd160(_) | Hash160(_) => Tree::Nullary,
1068 And(ref subs) => Tree::Nary(subs.iter().map(Arc::clone).collect()),
1069 Or(ref v) => Tree::Nary(v.iter().map(|(_, p)| Arc::clone(p)).collect()),
1070 Thresh(ref thresh) => Tree::Nary(thresh.iter().map(Arc::clone).collect()),
1071 }
1072 }
1073}
1074
1075#[cfg(all(test, feature = "compiler"))]
1076mod compiler_tests {
1077 use core::str::FromStr;
1078
1079 use super::*;
1080
1081 #[test]
1082 fn test_gen_comb() {
1083 let policies: Vec<Arc<Concrete<String>>> = vec!["pk(A)", "pk(B)", "pk(C)", "pk(D)"]
1084 .into_iter()
1085 .map(|st| policy_str!("{}", st))
1086 .map(Arc::new)
1087 .collect();
1088 let thresh = Threshold::new(2, policies).unwrap();
1089
1090 let combinations = generate_combination(&thresh, 1.0);
1091
1092 let comb_a: Vec<Policy<String>> = vec![
1093 policy_str!("pk(B)"),
1094 policy_str!("pk(C)"),
1095 policy_str!("pk(D)"),
1096 ];
1097 let comb_b: Vec<Policy<String>> = vec![
1098 policy_str!("pk(A)"),
1099 policy_str!("pk(C)"),
1100 policy_str!("pk(D)"),
1101 ];
1102 let comb_c: Vec<Policy<String>> = vec![
1103 policy_str!("pk(A)"),
1104 policy_str!("pk(B)"),
1105 policy_str!("pk(D)"),
1106 ];
1107 let comb_d: Vec<Policy<String>> = vec![
1108 policy_str!("pk(A)"),
1109 policy_str!("pk(B)"),
1110 policy_str!("pk(C)"),
1111 ];
1112 let expected_comb = vec![comb_a, comb_b, comb_c, comb_d]
1113 .into_iter()
1114 .map(|sub_pol| {
1115 let expected_thresh =
1116 Threshold::from_iter(2, sub_pol.into_iter().map(Arc::new)).unwrap();
1117 (0.25, Arc::new(Policy::Thresh(expected_thresh)))
1118 })
1119 .collect::<Vec<_>>();
1120 assert_eq!(combinations, expected_comb);
1121 }
1122}
1123
1124#[cfg(test)]
1125mod tests {
1126 use std::str::FromStr;
1127
1128 use super::*;
1129
1130 #[test]
1131 fn for_each_key_count_keys() {
1132 let liquid_pol = Policy::<String>::from_str(
1133 "or(and(older(4096),thresh(2,pk(A),pk(B),pk(C))),thresh(11,pk(F1),pk(F2),pk(F3),pk(F4),pk(F5),pk(F6),pk(F7),pk(F8),pk(F9),pk(F10),pk(F11),pk(F12),pk(F13),pk(F14)))").unwrap();
1134 let mut count = 0;
1135 assert!(liquid_pol.for_each_key(|_| {
1136 count += 1;
1137 true
1138 }));
1139 assert_eq!(count, 17);
1140 }
1141
1142 #[test]
1143 fn for_each_key_fails_predicate() {
1144 let policy =
1145 Policy::<String>::from_str("or(and(pk(key0),pk(key1)),pk(oddnamedkey))").unwrap();
1146 assert!(!policy.for_each_key(|k| k.starts_with("key")));
1147 }
1148
1149 #[test]
1150 fn tranaslate_pk() {
1151 pub struct TestTranslator;
1152 impl Translator<String, String, ()> for TestTranslator {
1153 fn pk(&mut self, pk: &String) -> Result<String, ()> {
1154 let new = format!("NEW-{}", pk);
1155 Ok(new.to_string())
1156 }
1157 fn sha256(&mut self, hash: &String) -> Result<String, ()> { Ok(hash.to_string()) }
1158 fn hash256(&mut self, hash: &String) -> Result<String, ()> { Ok(hash.to_string()) }
1159 fn ripemd160(&mut self, hash: &String) -> Result<String, ()> { Ok(hash.to_string()) }
1160 fn hash160(&mut self, hash: &String) -> Result<String, ()> { Ok(hash.to_string()) }
1161 }
1162 let policy = Policy::<String>::from_str("or(and(pk(A),pk(B)),pk(C))").unwrap();
1163 let mut t = TestTranslator;
1164
1165 let want = Policy::<String>::from_str("or(and(pk(NEW-A),pk(NEW-B)),pk(NEW-C))").unwrap();
1166 let got = policy
1167 .translate_pk(&mut t)
1168 .expect("failed to translate keys");
1169
1170 assert_eq!(got, want);
1171 }
1172
1173 #[test]
1174 fn translate_unsatisfiable_pk() {
1175 let policy = Policy::<String>::from_str("or(and(pk(A),pk(B)),pk(C))").unwrap();
1176
1177 let want = Policy::<String>::from_str("or(and(pk(A),UNSATISFIABLE),pk(C))").unwrap();
1178 let got = policy.translate_unsatisfiable_pk(&"B".to_string());
1179
1180 assert_eq!(got, want);
1181 }
1182
1183 #[test]
1184 fn keys() {
1185 let policy = Policy::<String>::from_str("or(and(pk(A),pk(B)),pk(C))").unwrap();
1186
1187 let want = vec!["A", "B", "C"];
1188 let got = policy.keys();
1189
1190 assert_eq!(got, want);
1191 }
1192
1193 #[test]
1194 #[cfg(feature = "compiler")]
1195 fn num_tap_leaves() {
1196 let policy = Policy::<String>::from_str("or(and(pk(A),pk(B)),pk(C))").unwrap();
1197 assert_eq!(policy.num_tap_leaves(), 2);
1198 }
1199
1200 #[test]
1201 #[should_panic]
1202 fn check_timelocks() {
1203 let _ = Policy::<String>::from_str("and(after(10),after(500000000))").unwrap();
1205 }
1206}