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