1#![allow(clippy::cast_precision_loss)] use std::collections::HashSet;
10use std::{error, fmt, str};
11
12use bitcoin_miniscript::expression::check_valid_chars;
13use elements::{LockTime, Sequence};
14#[cfg(feature = "compiler")]
15use {
16 crate::descriptor::TapTree,
17 crate::miniscript::ScriptContext,
18 crate::policy::compiler::CompilerError,
19 crate::policy::compiler::OrdF64,
20 crate::policy::{compiler, Concrete, Liftable, Semantic},
21 crate::Descriptor,
22 crate::Miniscript,
23 crate::NoExt,
24 crate::Tap,
25 std::cmp::Reverse,
26 std::collections::{BTreeSet, BinaryHeap, HashMap},
27 std::sync::Arc,
28};
29
30use super::ENTAILMENT_MAX_TERMINALS;
31use crate::expression::{self, FromTree};
32use crate::miniscript::types::extra_props::TimelockInfo;
33#[cfg(all(doc, not(feature = "compiler")))]
34use crate::Descriptor;
35use crate::{errstr, AbsLockTime, Error, ForEachKey, MiniscriptKey, Translator};
36
37#[cfg(feature = "compiler")]
39const MAX_COMPILATION_LEAVES: usize = 1024;
40
41#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
45pub enum Policy<Pk: MiniscriptKey> {
46 Unsatisfiable,
48 Trivial,
50 Key(Pk),
52 After(AbsLockTime),
54 Older(Sequence),
56 Sha256(Pk::Sha256),
58 Hash256(Pk::Hash256),
60 Ripemd160(Pk::Ripemd160),
62 Hash160(Pk::Hash160),
64 And(Vec<Policy<Pk>>),
66 Or(Vec<(usize, Policy<Pk>)>),
69 Threshold(usize, Vec<Policy<Pk>>),
71}
72
73impl<Pk> Policy<Pk>
74where
75 Pk: MiniscriptKey,
76{
77 pub fn after(n: u32) -> Policy<Pk> {
80 Policy::After(AbsLockTime::from(LockTime::from_consensus(n)))
81 }
82
83 pub fn older(n: u32) -> Policy<Pk> {
86 Policy::Older(Sequence::from_consensus(n))
87 }
88}
89
90#[cfg(feature = "compiler")]
94#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
95enum PolicyArc<Pk: MiniscriptKey> {
96 Unsatisfiable,
98 Trivial,
100 Key(Pk),
102 After(u32),
104 Older(u32),
106 Sha256(Pk::Sha256),
108 Hash256(Pk::Hash256),
110 Ripemd160(Pk::Ripemd160),
112 Hash160(Pk::Hash160),
114 And(Vec<Arc<PolicyArc<Pk>>>),
116 Or(Vec<(usize, Arc<PolicyArc<Pk>>)>),
119 Threshold(usize, Vec<Arc<PolicyArc<Pk>>>),
121}
122
123#[cfg(feature = "compiler")]
124impl<Pk: MiniscriptKey> From<PolicyArc<Pk>> for Policy<Pk> {
125 fn from(p: PolicyArc<Pk>) -> Self {
126 match p {
127 PolicyArc::Unsatisfiable => Policy::Unsatisfiable,
128 PolicyArc::Trivial => Policy::Trivial,
129 PolicyArc::Key(pk) => Policy::Key(pk),
130 PolicyArc::After(t) => Policy::After(AbsLockTime::from(LockTime::from_consensus(t))),
131 PolicyArc::Older(t) => Policy::Older(Sequence::from_consensus(t)),
132 PolicyArc::Sha256(hash) => Policy::Sha256(hash),
133 PolicyArc::Hash256(hash) => Policy::Hash256(hash),
134 PolicyArc::Ripemd160(hash) => Policy::Ripemd160(hash),
135 PolicyArc::Hash160(hash) => Policy::Hash160(hash),
136 PolicyArc::And(subs) => Policy::And(
137 subs.into_iter()
138 .map(|pol| Self::from((*pol).clone()))
139 .collect(),
140 ),
141 PolicyArc::Or(subs) => Policy::Or(
142 subs.into_iter()
143 .map(|(odds, sub)| (odds, Self::from((*sub).clone())))
144 .collect(),
145 ),
146 PolicyArc::Threshold(k, subs) => Policy::Threshold(
147 k,
148 subs.into_iter()
149 .map(|pol| Self::from((*pol).clone()))
150 .collect(),
151 ),
152 }
153 }
154}
155
156#[cfg(feature = "compiler")]
157impl<Pk: MiniscriptKey> From<Policy<Pk>> for PolicyArc<Pk> {
158 fn from(p: Policy<Pk>) -> Self {
159 match p {
160 Policy::Unsatisfiable => PolicyArc::Unsatisfiable,
161 Policy::Trivial => PolicyArc::Trivial,
162 Policy::Key(pk) => PolicyArc::Key(pk),
163 Policy::After(t) => PolicyArc::After(t.to_consensus_u32()),
164 Policy::Older(Sequence(t)) => PolicyArc::Older(t),
165 Policy::Sha256(hash) => PolicyArc::Sha256(hash),
166 Policy::Hash256(hash) => PolicyArc::Hash256(hash),
167 Policy::Ripemd160(hash) => PolicyArc::Ripemd160(hash),
168 Policy::Hash160(hash) => PolicyArc::Hash160(hash),
169 Policy::And(subs) => PolicyArc::And(
170 subs.iter()
171 .map(|sub| Arc::new(Self::from(sub.clone())))
172 .collect(),
173 ),
174 Policy::Or(subs) => PolicyArc::Or(
175 subs.iter()
176 .map(|(odds, sub)| (*odds, Arc::new(Self::from(sub.clone()))))
177 .collect(),
178 ),
179 Policy::Threshold(k, subs) => PolicyArc::Threshold(
180 k,
181 subs.iter()
182 .map(|sub| Arc::new(Self::from(sub.clone())))
183 .collect(),
184 ),
185 }
186 }
187}
188
189#[derive(Copy, Clone, PartialEq, Eq, Debug)]
191pub enum PolicyError {
192 NonBinaryArgAnd,
194 NonBinaryArgOr,
196 IncorrectThresh,
198 ZeroTime,
200 TimeTooFar,
202 InsufficientArgsforAnd,
204 InsufficientArgsforOr,
206 EntailmentMaxTerminals,
208 HeightTimelockCombination,
211 DuplicatePubKeys,
213}
214
215pub enum DescriptorCtx<Pk> {
217 Bare,
219 Sh,
221 Wsh,
223 ShWsh,
225 Tr(Option<Pk>),
228}
229
230impl fmt::Display for PolicyError {
231 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
232 match *self {
233 PolicyError::NonBinaryArgAnd => {
234 f.write_str("And policy fragment must take 2 arguments")
235 }
236 PolicyError::NonBinaryArgOr => f.write_str("Or policy fragment must take 2 arguments"),
237 PolicyError::IncorrectThresh => {
238 f.write_str("Threshold k must be greater than 0 and less than or equal to n 0<k<=n")
239 }
240 PolicyError::TimeTooFar => {
241 f.write_str("Relative/Absolute time must be less than 2^31; n < 2^31")
242 }
243 PolicyError::ZeroTime => f.write_str("Time must be greater than 0; n > 0"),
244 PolicyError::InsufficientArgsforAnd => {
245 f.write_str("Semantic Policy 'And' fragment must have at least 2 args ")
246 }
247 PolicyError::InsufficientArgsforOr => {
248 f.write_str("Semantic Policy 'Or' fragment must have at least 2 args ")
249 }
250 PolicyError::EntailmentMaxTerminals => write!(
251 f,
252 "Policy entailment only supports {} terminals",
253 ENTAILMENT_MAX_TERMINALS
254 ),
255 PolicyError::HeightTimelockCombination => {
256 f.write_str("Cannot lift policies that have a heightlock and timelock combination")
257 }
258 PolicyError::DuplicatePubKeys => f.write_str("Policy contains duplicate keys"),
259 }
260 }
261}
262
263impl error::Error for PolicyError {
264 fn cause(&self) -> Option<&dyn error::Error> {
265 use self::PolicyError::*;
266
267 match self {
268 NonBinaryArgAnd
269 | NonBinaryArgOr
270 | IncorrectThresh
271 | ZeroTime
272 | TimeTooFar
273 | InsufficientArgsforAnd
274 | InsufficientArgsforOr
275 | EntailmentMaxTerminals
276 | HeightTimelockCombination
277 | DuplicatePubKeys => None,
278 }
279 }
280}
281
282impl<Pk: MiniscriptKey> Policy<Pk> {
283 #[cfg(feature = "compiler")]
306 fn to_tapleaf_prob_vec(&self, prob: f64) -> Vec<(f64, Policy<Pk>)> {
307 match self {
308 Policy::Or(ref subs) => {
309 let total_odds: usize = subs.iter().map(|(ref k, _)| k).sum();
310 subs.iter()
311 .flat_map(|(k, ref policy)| {
312 policy.to_tapleaf_prob_vec(prob * *k as f64 / total_odds as f64)
313 })
314 .collect::<Vec<_>>()
315 }
316 Policy::Threshold(k, ref subs) if *k == 1 => {
317 let total_odds = subs.len();
318 subs.iter()
319 .flat_map(|policy| policy.to_tapleaf_prob_vec(prob / total_odds as f64))
320 .collect::<Vec<_>>()
321 }
322 x => vec![(prob, x.clone())],
323 }
324 }
325
326 #[cfg(feature = "compiler")]
328 fn extract_key(self, unspendable_key: Option<Pk>) -> Result<(Pk, Policy<Pk>), Error> {
329 let mut internal_key: Option<Pk> = None;
330 {
331 let mut prob = 0.;
332 let semantic_policy = self.lift()?;
333 let concrete_keys = self.keys();
334 let key_prob_map: HashMap<_, _> = self
335 .to_tapleaf_prob_vec(1.0)
336 .into_iter()
337 .filter(|(_, pol)| matches!(*pol, Concrete::Key(..)))
338 .map(|(prob, key)| (key, prob))
339 .collect();
340
341 for key in concrete_keys.into_iter() {
342 if semantic_policy
343 .clone()
344 .satisfy_constraint(&Semantic::Key(key.clone()), true)
345 == Semantic::Trivial
346 {
347 match key_prob_map.get(&Concrete::Key(key.clone())) {
348 Some(val) => {
349 if *val > prob {
350 prob = *val;
351 internal_key = Some(key.clone());
352 }
353 }
354 None => return Err(errstr("Key should have existed in the HashMap!")),
355 }
356 }
357 }
358 }
359 match (internal_key, unspendable_key) {
360 (Some(ref key), _) => Ok((key.clone(), self.translate_unsatisfiable_pk(key))),
361 (_, Some(key)) => Ok((key, self)),
362 _ => Err(errstr("No viable internal key found.")),
363 }
364 }
365
366 #[cfg(feature = "compiler")]
383 pub fn compile_tr(&self, unspendable_key: Option<Pk>) -> Result<Descriptor<Pk, NoExt>, Error> {
384 self.is_valid()?; match self.is_safe_nonmalleable() {
386 (false, _) => Err(Error::from(CompilerError::TopLevelNonSafe)),
387 (_, false) => Err(Error::from(
388 CompilerError::ImpossibleNonMalleableCompilation,
389 )),
390 _ => {
391 let (internal_key, policy) = self.clone().extract_key(unspendable_key)?;
392 policy.check_num_tapleaves()?;
393 let tree = Descriptor::new_tr(
394 internal_key,
395 match policy {
396 Policy::Trivial => None,
397 policy => {
398 let vec_policies: Vec<_> = policy.to_tapleaf_prob_vec(1.0);
399 let mut leaf_compilations: Vec<(OrdF64, Miniscript<Pk, Tap>)> = vec![];
400 for (prob, pol) in vec_policies {
401 if pol == Policy::Unsatisfiable {
403 continue;
404 }
405 let compilation = compiler::best_compilation::<Pk, Tap>(&pol)?;
406 compilation.sanity_check()?;
407 leaf_compilations.push((OrdF64(prob), compilation));
408 }
409 let taptree = with_huffman_tree::<Pk>(leaf_compilations)?;
410 Some(taptree)
411 }
412 },
413 )?;
414 Ok(tree)
415 }
416 }
417 }
418
419 #[cfg(feature = "compiler")]
440 pub fn compile_tr_private_experimental(
441 &self,
442 unspendable_key: Option<Pk>,
443 ) -> Result<Descriptor<Pk>, Error> {
444 self.is_valid()?; match self.is_safe_nonmalleable() {
446 (false, _) => Err(Error::from(CompilerError::TopLevelNonSafe)),
447 (_, false) => Err(Error::from(
448 CompilerError::ImpossibleNonMalleableCompilation,
449 )),
450 _ => {
451 let (internal_key, policy) = self.clone().extract_key(unspendable_key)?;
452 let tree = Descriptor::new_tr(
453 internal_key,
454 match policy {
455 Policy::Trivial => None,
456 policy => {
457 let pol = PolicyArc::from(policy);
458 let leaf_compilations: Vec<_> = pol
459 .enumerate_policy_tree(1.0)
460 .into_iter()
461 .filter(|x| x.1 != Arc::new(PolicyArc::Unsatisfiable))
462 .map(|(prob, ref pol)| {
463 let converted_pol = Policy::<Pk>::from((**pol).clone());
464 (
465 OrdF64(prob),
466 compiler::best_compilation(&converted_pol).unwrap(),
467 )
468 })
469 .collect();
470 let taptree = with_huffman_tree::<Pk>(leaf_compilations).unwrap();
471 Some(taptree)
472 }
473 },
474 )?;
475 Ok(tree)
476 }
477 }
478 }
479
480 #[cfg(feature = "compiler")]
491 pub fn compile_to_descriptor<Ctx: ScriptContext>(
492 &self,
493 desc_ctx: DescriptorCtx<Pk>,
494 ) -> Result<Descriptor<Pk, NoExt>, Error> {
495 self.is_valid()?;
496 match self.is_safe_nonmalleable() {
497 (false, _) => Err(Error::from(CompilerError::TopLevelNonSafe)),
498 (_, false) => Err(Error::from(
499 CompilerError::ImpossibleNonMalleableCompilation,
500 )),
501 _ => match desc_ctx {
502 DescriptorCtx::Bare => Descriptor::new_bare(compiler::best_compilation(self)?),
503 DescriptorCtx::Sh => Descriptor::new_sh(compiler::best_compilation(self)?),
504 DescriptorCtx::Wsh => Descriptor::new_wsh(compiler::best_compilation(self)?),
505 DescriptorCtx::ShWsh => Descriptor::new_sh_wsh(compiler::best_compilation(self)?),
506 DescriptorCtx::Tr(unspendable_key) => self.compile_tr(unspendable_key),
507 },
508 }
509 }
510
511 #[cfg(feature = "compiler")]
519 pub fn compile<Ctx: ScriptContext>(&self) -> Result<Miniscript<Pk, Ctx>, CompilerError> {
520 self.is_valid()?;
521 match self.is_safe_nonmalleable() {
522 (false, _) => Err(CompilerError::TopLevelNonSafe),
523 (_, false) => Err(CompilerError::ImpossibleNonMalleableCompilation),
524 _ => compiler::best_compilation(self),
525 }
526 }
527}
528
529#[cfg(feature = "compiler")]
530impl<Pk: MiniscriptKey> PolicyArc<Pk> {
531 #[cfg(feature = "compiler")]
536 fn enumerate_pol(&self, prob: f64) -> Vec<(f64, Arc<Self>)> {
537 match self {
538 PolicyArc::Or(subs) => {
539 let total_odds = subs.iter().fold(0, |acc, x| acc + x.0);
540 subs.iter()
541 .map(|(odds, pol)| (prob * *odds as f64 / total_odds as f64, pol.clone()))
542 .collect::<Vec<_>>()
543 }
544 PolicyArc::Threshold(k, subs) if *k == 1 => {
545 let total_odds = subs.len();
546 subs.iter()
547 .map(|pol| (prob / total_odds as f64, pol.clone()))
548 .collect::<Vec<_>>()
549 }
550 PolicyArc::Threshold(k, subs) if *k != subs.len() => {
551 generate_combination(subs, prob, *k)
552 }
553 pol => vec![(prob, Arc::new(pol.clone()))],
554 }
555 }
556
557 #[cfg(feature = "compiler")]
566 fn enumerate_policy_tree(self, prob: f64) -> Vec<(f64, Arc<Self>)> {
567 let mut tapleaf_prob_vec = BTreeSet::<(Reverse<OrdF64>, Arc<Self>)>::new();
568 let mut pol_prob_map = HashMap::<Arc<Self>, OrdF64>::new();
573
574 let arc_self = Arc::new(self);
575 tapleaf_prob_vec.insert((Reverse(OrdF64(prob)), Arc::clone(&arc_self)));
576 pol_prob_map.insert(Arc::clone(&arc_self), OrdF64(prob));
577
578 let mut prev_len = 0usize;
582 let mut enum_len = tapleaf_prob_vec.len();
585
586 let mut ret: Vec<(f64, Arc<Self>)> = vec![];
587
588 'outer: loop {
590 let mut prob: Reverse<OrdF64> = Reverse(OrdF64(0.0));
592 let mut curr_policy: Arc<Self> = Arc::new(PolicyArc::Unsatisfiable);
593 let mut curr_pol_replace_vec: Vec<(f64, Arc<Self>)> = vec![];
594 let mut no_more_enum = false;
595
596 let mut to_del: Vec<(f64, Arc<Self>)> = vec![];
599 'inner: for (i, (p, pol)) in tapleaf_prob_vec.iter().enumerate() {
600 curr_pol_replace_vec = pol.enumerate_pol(p.0 .0);
601 enum_len += curr_pol_replace_vec.len() - 1; assert!(prev_len <= enum_len);
603
604 if prev_len < enum_len {
605 prob = *p;
607 curr_policy = Arc::clone(pol);
608 break 'inner;
609 } else if i == tapleaf_prob_vec.len() - 1 {
610 no_more_enum = true;
613 } else {
614 to_del.push((p.0 .0, Arc::clone(pol)));
618 }
619 }
620
621 if enum_len > MAX_COMPILATION_LEAVES || no_more_enum {
623 for (p, pol) in tapleaf_prob_vec.into_iter() {
624 ret.push((p.0 .0, pol));
625 }
626 break 'outer;
627 }
628
629 assert!(tapleaf_prob_vec.remove(&(prob, curr_policy.clone())));
634
635 for (p, pol) in to_del {
637 assert!(tapleaf_prob_vec.remove(&(Reverse(OrdF64(p)), pol.clone())));
638 ret.push((p, pol.clone()));
639 }
640
641 for (p, policy) in curr_pol_replace_vec {
643 match pol_prob_map.get(&policy) {
644 Some(prev_prob) => {
645 assert!(tapleaf_prob_vec.remove(&(Reverse(*prev_prob), policy.clone())));
646 tapleaf_prob_vec.insert((Reverse(OrdF64(prev_prob.0 + p)), policy.clone()));
647 pol_prob_map.insert(policy.clone(), OrdF64(prev_prob.0 + p));
648 }
649 None => {
650 tapleaf_prob_vec.insert((Reverse(OrdF64(p)), policy.clone()));
651 pol_prob_map.insert(policy.clone(), OrdF64(p));
652 }
653 }
654 }
655 prev_len = enum_len;
657 }
658
659 ret
660 }
661}
662
663impl<Pk: MiniscriptKey> ForEachKey<Pk> for Policy<Pk> {
664 fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
665 where
666 Pk: 'a,
667 {
668 self.for_each_key_internal(&mut pred)
669 }
670}
671
672impl<Pk: MiniscriptKey> Policy<Pk> {
673 fn for_each_key_internal<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool {
674 match *self {
675 Policy::Unsatisfiable | Policy::Trivial => true,
676 Policy::Key(ref pk) => pred(pk),
677 Policy::Sha256(..)
678 | Policy::Hash256(..)
679 | Policy::Ripemd160(..)
680 | Policy::Hash160(..)
681 | Policy::After(..)
682 | Policy::Older(..) => true,
683 Policy::Threshold(_, ref subs) | Policy::And(ref subs) => {
684 subs.iter().all(|sub| sub.for_each_key_internal(pred))
685 }
686 Policy::Or(ref subs) => subs.iter().all(|(_, sub)| sub.for_each_key_internal(pred)),
687 }
688 }
689
690 pub fn translate_pk<Q, E, T>(&self, t: &mut T) -> Result<Policy<Q>, E>
734 where
735 T: Translator<Pk, Q, E>,
736 Q: MiniscriptKey,
737 {
738 self._translate_pk(t)
739 }
740
741 fn _translate_pk<Q, E, T>(&self, t: &mut T) -> Result<Policy<Q>, E>
742 where
743 T: Translator<Pk, Q, E>,
744 Q: MiniscriptKey,
745 {
746 match *self {
747 Policy::Unsatisfiable => Ok(Policy::Unsatisfiable),
748 Policy::Trivial => Ok(Policy::Trivial),
749 Policy::Key(ref pk) => t.pk(pk).map(Policy::Key),
750 Policy::Sha256(ref h) => t.sha256(h).map(Policy::Sha256),
751 Policy::Hash256(ref h) => t.hash256(h).map(Policy::Hash256),
752 Policy::Ripemd160(ref h) => t.ripemd160(h).map(Policy::Ripemd160),
753 Policy::Hash160(ref h) => t.hash160(h).map(Policy::Hash160),
754 Policy::Older(n) => Ok(Policy::Older(n)),
755 Policy::After(n) => Ok(Policy::After(n)),
756 Policy::Threshold(k, ref subs) => {
757 let new_subs: Result<Vec<Policy<Q>>, _> =
758 subs.iter().map(|sub| sub._translate_pk(t)).collect();
759 new_subs.map(|ok| Policy::Threshold(k, ok))
760 }
761 Policy::And(ref subs) => Ok(Policy::And(
762 subs.iter()
763 .map(|sub| sub._translate_pk(t))
764 .collect::<Result<Vec<Policy<Q>>, E>>()?,
765 )),
766 Policy::Or(ref subs) => Ok(Policy::Or(
767 subs.iter()
768 .map(|(prob, sub)| Ok((*prob, sub._translate_pk(t)?)))
769 .collect::<Result<Vec<(usize, Policy<Q>)>, E>>()?,
770 )),
771 }
772 }
773
774 pub fn translate_unsatisfiable_pk(self, key: &Pk) -> Policy<Pk> {
776 match self {
777 Policy::Key(ref k) if k.clone() == *key => Policy::Unsatisfiable,
778 Policy::And(subs) => Policy::And(
779 subs.into_iter()
780 .map(|sub| sub.translate_unsatisfiable_pk(key))
781 .collect::<Vec<_>>(),
782 ),
783 Policy::Or(subs) => Policy::Or(
784 subs.into_iter()
785 .map(|(k, sub)| (k, sub.translate_unsatisfiable_pk(key)))
786 .collect::<Vec<_>>(),
787 ),
788 Policy::Threshold(k, subs) => Policy::Threshold(
789 k,
790 subs.into_iter()
791 .map(|sub| sub.translate_unsatisfiable_pk(key))
792 .collect::<Vec<_>>(),
793 ),
794 x => x,
795 }
796 }
797
798 pub fn keys(&self) -> Vec<&Pk> {
800 match self {
801 Policy::Key(ref pk) => vec![pk],
802 Policy::Threshold(_k, ref subs) => {
803 subs.iter().flat_map(|sub| sub.keys()).collect::<Vec<_>>()
804 }
805 Policy::And(subs) => subs.iter().flat_map(|sub| sub.keys()).collect::<Vec<_>>(),
806 Policy::Or(ref subs) => subs
807 .iter()
808 .flat_map(|(ref _k, ref sub)| sub.keys())
809 .collect::<Vec<_>>(),
810 _ => vec![],
812 }
813 }
814
815 #[cfg(feature = "compiler")]
818 fn num_tap_leaves(&self) -> usize {
819 match self {
820 Policy::Or(subs) => subs.iter().map(|(_prob, pol)| pol.num_tap_leaves()).sum(),
821 Policy::Threshold(k, subs) if *k == 1 => {
822 subs.iter().map(|pol| pol.num_tap_leaves()).sum()
823 }
824 _ => 1,
825 }
826 }
827
828 #[cfg(feature = "compiler")]
830 fn check_num_tapleaves(&self) -> Result<(), Error> {
831 if self.num_tap_leaves() > MAX_COMPILATION_LEAVES {
832 return Err(errstr("Too many Tapleaves"));
833 }
834 Ok(())
835 }
836
837 pub fn check_duplicate_keys(&self) -> Result<(), PolicyError> {
839 let pks = self.keys();
840 let pks_len = pks.len();
841 let unique_pks_len = pks.into_iter().collect::<HashSet<_>>().len();
842
843 if pks_len > unique_pks_len {
844 Err(PolicyError::DuplicatePubKeys)
845 } else {
846 Ok(())
847 }
848 }
849
850 pub fn check_timelocks(&self) -> Result<(), PolicyError> {
855 let timelocks = self.check_timelocks_helper();
856 if timelocks.contains_combination {
857 Err(PolicyError::HeightTimelockCombination)
858 } else {
859 Ok(())
860 }
861 }
862
863 fn check_timelocks_helper(&self) -> TimelockInfo {
866 match *self {
868 Policy::Unsatisfiable
869 | Policy::Trivial
870 | Policy::Key(_)
871 | Policy::Sha256(_)
872 | Policy::Hash256(_)
873 | Policy::Ripemd160(_)
874 | Policy::Hash160(_) => TimelockInfo::default(),
875 Policy::After(t) => TimelockInfo {
876 csv_with_height: false,
877 csv_with_time: false,
878 cltv_with_height: LockTime::from(t).is_block_height(),
879 cltv_with_time: LockTime::from(t).is_block_time(),
880 contains_combination: false,
881 },
882 Policy::Older(t) => TimelockInfo {
883 csv_with_height: t.is_height_locked(),
884 csv_with_time: t.is_time_locked(),
885 cltv_with_height: false,
886 cltv_with_time: false,
887 contains_combination: false,
888 },
889 Policy::Threshold(k, ref subs) => {
890 let iter = subs.iter().map(|sub| sub.check_timelocks_helper());
891 TimelockInfo::combine_threshold(k, iter)
892 }
893 Policy::And(ref subs) => {
894 let iter = subs.iter().map(|sub| sub.check_timelocks_helper());
895 TimelockInfo::combine_threshold(subs.len(), iter)
896 }
897 Policy::Or(ref subs) => {
898 let iter = subs.iter().map(|(_p, sub)| sub.check_timelocks_helper());
899 TimelockInfo::combine_threshold(1, iter)
900 }
901 }
902 }
903
904 pub fn is_valid(&self) -> Result<(), PolicyError> {
909 self.check_timelocks()?;
910 self.check_duplicate_keys()?;
911 match *self {
912 Policy::And(ref subs) => {
913 if subs.len() != 2 {
914 Err(PolicyError::NonBinaryArgAnd)
915 } else {
916 subs.iter()
917 .map(|sub| sub.is_valid())
918 .collect::<Result<Vec<()>, PolicyError>>()?;
919 Ok(())
920 }
921 }
922 Policy::Or(ref subs) => {
923 if subs.len() != 2 {
924 Err(PolicyError::NonBinaryArgOr)
925 } else {
926 subs.iter()
927 .map(|(_prob, sub)| sub.is_valid())
928 .collect::<Result<Vec<()>, PolicyError>>()?;
929 Ok(())
930 }
931 }
932 Policy::Threshold(k, ref subs) => {
933 if k == 0 || k > subs.len() {
934 Err(PolicyError::IncorrectThresh)
935 } else {
936 subs.iter()
937 .map(|sub| sub.is_valid())
938 .collect::<Result<Vec<()>, PolicyError>>()?;
939 Ok(())
940 }
941 }
942 Policy::After(n) => {
943 if n == LockTime::ZERO.into() {
944 Err(PolicyError::ZeroTime)
945 } else if n.to_u32() > 2u32.pow(31) {
946 Err(PolicyError::TimeTooFar)
947 } else {
948 Ok(())
949 }
950 }
951 Policy::Older(n) => {
952 if n == Sequence::ZERO {
953 Err(PolicyError::ZeroTime)
954 } else if n.to_consensus_u32() > 2u32.pow(31) {
955 Err(PolicyError::TimeTooFar)
956 } else {
957 Ok(())
958 }
959 }
960 _ => Ok(()),
961 }
962 }
963 pub fn is_safe_nonmalleable(&self) -> (bool, bool) {
969 match *self {
970 Policy::Unsatisfiable | Policy::Trivial => (true, true),
971 Policy::Key(_) => (true, true),
972 Policy::Sha256(_)
973 | Policy::Hash256(_)
974 | Policy::Ripemd160(_)
975 | Policy::Hash160(_)
976 | Policy::After(_)
977 | Policy::Older(_) => (false, true),
978 Policy::Threshold(k, ref subs) => {
979 let (safe_count, non_mall_count) = subs
980 .iter()
981 .map(|sub| sub.is_safe_nonmalleable())
982 .fold((0, 0), |(safe_count, non_mall_count), (safe, non_mall)| {
983 (
984 safe_count + usize::from(safe),
985 non_mall_count + usize::from(non_mall),
986 )
987 });
988 (
989 safe_count >= (subs.len() - k + 1),
990 non_mall_count == subs.len() && safe_count >= (subs.len() - k),
991 )
992 }
993 Policy::And(ref subs) => {
994 let (atleast_one_safe, all_non_mall) = subs
995 .iter()
996 .map(|sub| sub.is_safe_nonmalleable())
997 .fold((false, true), |acc, x| (acc.0 || x.0, acc.1 && x.1));
998 (atleast_one_safe, all_non_mall)
999 }
1000
1001 Policy::Or(ref subs) => {
1002 let (all_safe, atleast_one_safe, all_non_mall) = subs
1003 .iter()
1004 .map(|(_, sub)| sub.is_safe_nonmalleable())
1005 .fold((true, false, true), |acc, x| {
1006 (acc.0 && x.0, acc.1 || x.0, acc.2 && x.1)
1007 });
1008 (all_safe, atleast_one_safe && all_non_mall)
1009 }
1010 }
1011 }
1012}
1013
1014impl<Pk: MiniscriptKey> fmt::Debug for Policy<Pk> {
1015 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1016 match *self {
1017 Policy::Unsatisfiable => f.write_str("UNSATISFIABLE()"),
1018 Policy::Trivial => f.write_str("TRIVIAL()"),
1019 Policy::Key(ref pk) => write!(f, "pk({:?})", pk),
1020 Policy::After(n) => write!(f, "after({})", n),
1021 Policy::Older(n) => write!(f, "older({})", n),
1022 Policy::Sha256(ref h) => write!(f, "sha256({})", h),
1023 Policy::Hash256(ref h) => write!(f, "hash256({})", h),
1024 Policy::Ripemd160(ref h) => write!(f, "ripemd160({})", h),
1025 Policy::Hash160(ref h) => write!(f, "hash160({})", h),
1026 Policy::And(ref subs) => {
1027 f.write_str("and(")?;
1028 if !subs.is_empty() {
1029 write!(f, "{:?}", subs[0])?;
1030 for sub in &subs[1..] {
1031 write!(f, ",{:?}", sub)?;
1032 }
1033 }
1034 f.write_str(")")
1035 }
1036 Policy::Or(ref subs) => {
1037 f.write_str("or(")?;
1038 if !subs.is_empty() {
1039 write!(f, "{}@{:?}", subs[0].0, subs[0].1)?;
1040 for sub in &subs[1..] {
1041 write!(f, ",{}@{:?}", sub.0, sub.1)?;
1042 }
1043 }
1044 f.write_str(")")
1045 }
1046 Policy::Threshold(k, ref subs) => {
1047 write!(f, "thresh({}", k)?;
1048 for sub in subs {
1049 write!(f, ",{:?}", sub)?;
1050 }
1051 f.write_str(")")
1052 }
1053 }
1054 }
1055}
1056
1057impl<Pk: MiniscriptKey> fmt::Display for Policy<Pk> {
1058 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1059 match *self {
1060 Policy::Unsatisfiable => f.write_str("UNSATISFIABLE"),
1061 Policy::Trivial => f.write_str("TRIVIAL"),
1062 Policy::Key(ref pk) => write!(f, "pk({})", pk),
1063 Policy::After(n) => write!(f, "after({})", n),
1064 Policy::Older(n) => write!(f, "older({})", n),
1065 Policy::Sha256(ref h) => write!(f, "sha256({})", h),
1066 Policy::Hash256(ref h) => write!(f, "hash256({})", h),
1067 Policy::Ripemd160(ref h) => write!(f, "ripemd160({})", h),
1068 Policy::Hash160(ref h) => write!(f, "hash160({})", h),
1069 Policy::And(ref subs) => {
1070 f.write_str("and(")?;
1071 if !subs.is_empty() {
1072 write!(f, "{}", subs[0])?;
1073 for sub in &subs[1..] {
1074 write!(f, ",{}", sub)?;
1075 }
1076 }
1077 f.write_str(")")
1078 }
1079 Policy::Or(ref subs) => {
1080 f.write_str("or(")?;
1081 if !subs.is_empty() {
1082 write!(f, "{}@{}", subs[0].0, subs[0].1)?;
1083 for sub in &subs[1..] {
1084 write!(f, ",{}@{}", sub.0, sub.1)?;
1085 }
1086 }
1087 f.write_str(")")
1088 }
1089 Policy::Threshold(k, ref subs) => {
1090 write!(f, "thresh({}", k)?;
1091 for sub in subs {
1092 write!(f, ",{}", sub)?;
1093 }
1094 f.write_str(")")
1095 }
1096 }
1097 }
1098}
1099
1100impl_from_str!(
1101 Policy<Pk>,
1102 type Err = Error;,
1103 fn from_str(s: &str) -> Result<Policy<Pk>, Error> {
1104 check_valid_chars(s)?;
1105
1106 let tree = expression::Tree::from_str(s)?;
1107 let policy: Policy<Pk> = FromTree::from_tree(&tree)?;
1108 policy.check_timelocks()?;
1109 Ok(policy)
1110 }
1111);
1112
1113serde_string_impl_pk!(Policy, "a miniscript concrete policy");
1114
1115#[rustfmt::skip]
1116impl_block_str!(
1117 Policy<Pk>,
1118 fn from_tree_prob(top: &expression::Tree, allow_prob: bool,)
1121 -> Result<(usize, Policy<Pk>), Error>
1122 {
1123 let frag_prob;
1124 let frag_name;
1125 let mut name_split = top.name.split('@');
1126 match (name_split.next(), name_split.next(), name_split.next()) {
1127 (None, _, _) => {
1128 frag_prob = 1;
1129 frag_name = "";
1130 }
1131 (Some(name), None, _) => {
1132 frag_prob = 1;
1133 frag_name = name;
1134 }
1135 (Some(prob), Some(name), None) => {
1136 if !allow_prob {
1137 return Err(Error::AtOutsideOr(top.name.to_owned()));
1138 }
1139 frag_prob = expression::parse_num::<u32>(prob)? as usize;
1140 frag_name = name;
1141 }
1142 (Some(_), Some(_), Some(_)) => {
1143 return Err(Error::MultiColon(top.name.to_owned()));
1144 }
1145 }
1146 match (frag_name, top.args.len() as u32) {
1147 ("UNSATISFIABLE", 0) => Ok(Policy::Unsatisfiable),
1148 ("TRIVIAL", 0) => Ok(Policy::Trivial),
1149 ("pk", 1) => expression::terminal(&top.args[0], |pk| Pk::from_str(pk).map(Policy::Key)),
1150 ("after", 1) => {
1151 let num = expression::terminal(&top.args[0], expression::parse_num)?;
1152 if num > 2u32.pow(31) {
1153 return Err(Error::PolicyError(PolicyError::TimeTooFar));
1154 } else if num == 0 {
1155 return Err(Error::PolicyError(PolicyError::ZeroTime));
1156 }
1157 Ok(Policy::after(num))
1158 }
1159 ("older", 1) => {
1160 let num = expression::terminal(&top.args[0], expression::parse_num)?;
1161 if num > 2u32.pow(31) {
1162 return Err(Error::PolicyError(PolicyError::TimeTooFar));
1163 } else if num == 0 {
1164 return Err(Error::PolicyError(PolicyError::ZeroTime));
1165 }
1166 Ok(Policy::older(num))
1167 }
1168 ("sha256", 1) => expression::terminal(&top.args[0], |x| {
1169 <Pk::Sha256 as core::str::FromStr>::from_str(x).map(Policy::Sha256)
1170 }),
1171 ("hash256", 1) => expression::terminal(&top.args[0], |x| {
1172 <Pk::Hash256 as core::str::FromStr>::from_str(x).map(Policy::Hash256)
1173 }),
1174 ("ripemd160", 1) => expression::terminal(&top.args[0], |x| {
1175 <Pk::Ripemd160 as core::str::FromStr>::from_str(x).map(Policy::Ripemd160)
1176 }),
1177 ("hash160", 1) => expression::terminal(&top.args[0], |x| {
1178 <Pk::Hash160 as core::str::FromStr>::from_str(x).map(Policy::Hash160)
1179 }),
1180 ("and", _) => {
1181 if top.args.len() != 2 {
1182 return Err(Error::PolicyError(PolicyError::NonBinaryArgAnd));
1183 }
1184 let mut subs = Vec::with_capacity(top.args.len());
1185 for arg in &top.args {
1186 subs.push(Policy::from_tree(arg)?);
1187 }
1188 Ok(Policy::And(subs))
1189 }
1190 ("or", _) => {
1191 if top.args.len() != 2 {
1192 return Err(Error::PolicyError(PolicyError::NonBinaryArgOr));
1193 }
1194 let mut subs = Vec::with_capacity(top.args.len());
1195 for arg in &top.args {
1196 subs.push(Policy::from_tree_prob(arg, true)?);
1197 }
1198 Ok(Policy::Or(subs))
1199 }
1200 ("thresh", nsubs) => {
1201 if top.args.is_empty() || !top.args[0].args.is_empty() {
1202 return Err(Error::PolicyError(PolicyError::IncorrectThresh));
1203 }
1204
1205 let thresh = expression::parse_num::<u32>(top.args[0].name)?;
1206 if thresh >= nsubs || thresh == 0 {
1207 return Err(Error::PolicyError(PolicyError::IncorrectThresh));
1208 }
1209
1210 let mut subs = Vec::with_capacity(top.args.len() - 1);
1211 for arg in &top.args[1..] {
1212 subs.push(Policy::from_tree(arg)?);
1213 }
1214 Ok(Policy::Threshold(thresh as usize, subs))
1215 }
1216 _ => Err(errstr(top.name)),
1217 }
1218 .map(|res| (frag_prob, res))
1219 }
1220);
1221
1222impl_from_tree!(
1223 Policy<Pk>,
1224 fn from_tree(top: &expression::Tree) -> Result<Policy<Pk>, Error> {
1225 Policy::from_tree_prob(top, false).map(|(_, result)| result)
1226 }
1227);
1228
1229#[cfg(feature = "compiler")]
1231fn with_huffman_tree<Pk: MiniscriptKey>(
1232 ms: Vec<(OrdF64, Miniscript<Pk, Tap>)>,
1233) -> Result<TapTree<Pk, NoExt>, Error> {
1234 let mut node_weights = BinaryHeap::<(Reverse<OrdF64>, TapTree<Pk>)>::new();
1235 for (prob, script) in ms {
1236 node_weights.push((Reverse(prob), TapTree::Leaf(Arc::new(script))));
1237 }
1238 if node_weights.is_empty() {
1239 return Err(errstr("Empty Miniscript compilation"));
1240 }
1241 while node_weights.len() > 1 {
1242 let (p1, s1) = node_weights.pop().expect("len must atleast be two");
1243 let (p2, s2) = node_weights.pop().expect("len must atleast be two");
1244
1245 let p = (p1.0).0 + (p2.0).0;
1246 node_weights.push((
1247 Reverse(OrdF64(p)),
1248 TapTree::Tree(Arc::from(s1), Arc::from(s2)),
1249 ));
1250 }
1251
1252 debug_assert!(node_weights.len() == 1);
1253 let node = node_weights
1254 .pop()
1255 .expect("huffman tree algorithm is broken")
1256 .1;
1257 Ok(node)
1258}
1259
1260#[cfg(feature = "compiler")]
1268fn generate_combination<Pk: MiniscriptKey>(
1269 policy_vec: &[Arc<PolicyArc<Pk>>],
1270 prob: f64,
1271 k: usize,
1272) -> Vec<(f64, Arc<PolicyArc<Pk>>)> {
1273 debug_assert!(k <= policy_vec.len());
1274
1275 let mut ret: Vec<(f64, Arc<PolicyArc<Pk>>)> = vec![];
1276 for i in 0..policy_vec.len() {
1277 let policies: Vec<Arc<PolicyArc<Pk>>> = policy_vec
1278 .iter()
1279 .enumerate()
1280 .filter_map(|(j, sub)| if j != i { Some(Arc::clone(sub)) } else { None })
1281 .collect();
1282 ret.push((
1283 prob / policy_vec.len() as f64,
1284 Arc::new(PolicyArc::Threshold(k, policies)),
1285 ));
1286 }
1287 ret
1288}
1289
1290#[cfg(all(test, feature = "compiler"))]
1291mod tests {
1292 use core::str::FromStr;
1293 use std::sync::Arc;
1294
1295 use super::Concrete;
1296 use crate::policy::concrete::{generate_combination, PolicyArc};
1297
1298 #[test]
1299 fn test_gen_comb() {
1300 let policies: Vec<Concrete<String>> = vec!["pk(A)", "pk(B)", "pk(C)", "pk(D)"]
1301 .into_iter()
1302 .map(|st| policy_str!("{}", st))
1303 .collect();
1304 let policy_vec = policies
1305 .into_iter()
1306 .map(|pol| Arc::new(PolicyArc::from(pol)))
1307 .collect::<Vec<_>>();
1308
1309 let combinations = generate_combination(&policy_vec, 1.0, 2);
1310
1311 let comb_a: Vec<Arc<PolicyArc<String>>> = vec![
1312 policy_str!("pk(B)"),
1313 policy_str!("pk(C)"),
1314 policy_str!("pk(D)"),
1315 ]
1316 .into_iter()
1317 .map(|pol| Arc::new(PolicyArc::from(pol)))
1318 .collect();
1319 let comb_b: Vec<Arc<PolicyArc<String>>> = vec![
1320 policy_str!("pk(A)"),
1321 policy_str!("pk(C)"),
1322 policy_str!("pk(D)"),
1323 ]
1324 .into_iter()
1325 .map(|pol| Arc::new(PolicyArc::from(pol)))
1326 .collect();
1327 let comb_c: Vec<Arc<PolicyArc<String>>> = vec![
1328 policy_str!("pk(A)"),
1329 policy_str!("pk(B)"),
1330 policy_str!("pk(D)"),
1331 ]
1332 .into_iter()
1333 .map(|pol| Arc::new(PolicyArc::from(pol)))
1334 .collect();
1335 let comb_d: Vec<Arc<PolicyArc<String>>> = vec![
1336 policy_str!("pk(A)"),
1337 policy_str!("pk(B)"),
1338 policy_str!("pk(C)"),
1339 ]
1340 .into_iter()
1341 .map(|pol| Arc::new(PolicyArc::from(pol)))
1342 .collect();
1343 let expected_comb = vec![comb_a, comb_b, comb_c, comb_d]
1344 .into_iter()
1345 .map(|sub_pol| (0.25, Arc::new(PolicyArc::Threshold(2, sub_pol))))
1346 .collect::<Vec<_>>();
1347 assert_eq!(combinations, expected_comb);
1348 }
1349}