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