1use core::str::FromStr;
9use core::{fmt, str};
10
11use bitcoin::{absolute, relative};
12
13use super::concrete::PolicyError;
14use super::ENTAILMENT_MAX_TERMINALS;
15use crate::iter::{Tree, TreeLike};
16use crate::prelude::*;
17use crate::sync::Arc;
18use crate::{
19 errstr, expression, AbsLockTime, Error, ForEachKey, FromStrKey, MiniscriptKey, RelLockTime,
20 Threshold, Translator,
21};
22
23#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
30pub enum Policy<Pk: MiniscriptKey> {
31 Unsatisfiable,
33 Trivial,
35 Key(Pk),
37 After(AbsLockTime),
39 Older(RelLockTime),
41 Sha256(Pk::Sha256),
43 Hash256(Pk::Hash256),
45 Ripemd160(Pk::Ripemd160),
47 Hash160(Pk::Hash160),
49 Thresh(Threshold<Arc<Policy<Pk>>, 0>),
51}
52
53impl<Pk: MiniscriptKey> ForEachKey<Pk> for Policy<Pk> {
54 fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
55 self.pre_order_iter().all(|policy| match policy {
56 Policy::Key(ref pk) => pred(pk),
57 _ => true,
58 })
59 }
60}
61
62impl<Pk: MiniscriptKey> Policy<Pk> {
63 pub fn translate_pk<Q, E, T>(&self, t: &mut T) -> Result<Policy<Q>, E>
105 where
106 T: Translator<Pk, Q, E>,
107 Q: MiniscriptKey,
108 {
109 use Policy::*;
110
111 let mut translated = vec![];
112 for data in self.post_order_iter() {
113 let new_policy = match data.node {
114 Unsatisfiable => Unsatisfiable,
115 Trivial => Trivial,
116 Key(ref pk) => t.pk(pk).map(Key)?,
117 Sha256(ref h) => t.sha256(h).map(Sha256)?,
118 Hash256(ref h) => t.hash256(h).map(Hash256)?,
119 Ripemd160(ref h) => t.ripemd160(h).map(Ripemd160)?,
120 Hash160(ref h) => t.hash160(h).map(Hash160)?,
121 Older(ref n) => Older(*n),
122 After(ref n) => After(*n),
123 Thresh(ref thresh) => {
124 Thresh(thresh.map_from_post_order_iter(&data.child_indices, &translated))
125 }
126 };
127 translated.push(Arc::new(new_policy));
128 }
129 let root_node = translated.pop().unwrap();
131 Ok(Arc::try_unwrap(root_node).unwrap())
133 }
134
135 pub fn entails(self, other: Policy<Pk>) -> Result<bool, PolicyError> {
144 if self.n_terminals() > ENTAILMENT_MAX_TERMINALS {
145 return Err(PolicyError::EntailmentMaxTerminals);
146 }
147 match (self, other) {
148 (Policy::Unsatisfiable, _) => Ok(true),
149 (Policy::Trivial, Policy::Trivial) => Ok(true),
150 (Policy::Trivial, _) => Ok(false),
151 (_, Policy::Unsatisfiable) => Ok(false),
152 (a, b) => {
153 let (a_norm, b_norm) = (a.normalized(), b.normalized());
154 let first_constraint = a_norm.first_constraint();
155 let (a1, b1) = (
156 a_norm.clone().satisfy_constraint(&first_constraint, true),
157 b_norm.clone().satisfy_constraint(&first_constraint, true),
158 );
159 let (a2, b2) = (
160 a_norm.satisfy_constraint(&first_constraint, false),
161 b_norm.satisfy_constraint(&first_constraint, false),
162 );
163 Ok(Policy::entails(a1, b1)? && Policy::entails(a2, b2)?)
164 }
165 }
166 }
167
168 fn n_terminals(&self) -> usize {
170 use Policy::*;
171
172 let mut n_terminals = vec![];
173 for data in self.post_order_iter() {
174 let n_terminals_for_child_n = |n| n_terminals[data.child_indices[n]];
175
176 let num = match data.node {
177 Thresh(thresh) => (0..thresh.n()).map(n_terminals_for_child_n).sum(),
178 Trivial | Unsatisfiable => 0,
179 _leaf => 1,
180 };
181 n_terminals.push(num);
182 }
183 n_terminals.pop().unwrap()
185 }
186
187 fn first_constraint(&self) -> Policy<Pk> {
191 debug_assert!(self.clone().normalized() == self.clone());
192 match self {
193 Policy::Thresh(ref thresh) => thresh.data()[0].first_constraint(),
194 first => first.clone(),
195 }
196 }
197
198 pub(crate) fn satisfy_constraint(self, witness: &Policy<Pk>, available: bool) -> Policy<Pk> {
203 debug_assert!(self.clone().normalized() == self);
204 if let Policy::Thresh { .. } = *witness {
205 panic!("should be unreachable")
207 }
208
209 let ret =
210 match self {
211 Policy::Thresh(thresh) => Policy::Thresh(thresh.map(|sub| {
212 Arc::new(sub.as_ref().clone().satisfy_constraint(witness, available))
213 })),
214 ref leaf if leaf == witness => {
215 if available {
216 Policy::Trivial
217 } else {
218 Policy::Unsatisfiable
219 }
220 }
221 x => x,
222 };
223 ret.normalized()
224 }
225}
226
227impl<Pk: MiniscriptKey> fmt::Debug for Policy<Pk> {
228 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
229 match *self {
230 Policy::Unsatisfiable => f.write_str("UNSATISFIABLE()"),
231 Policy::Trivial => f.write_str("TRIVIAL()"),
232 Policy::Key(ref pkh) => write!(f, "pk({:?})", pkh),
233 Policy::After(n) => write!(f, "after({})", n),
234 Policy::Older(n) => write!(f, "older({})", n),
235 Policy::Sha256(ref h) => write!(f, "sha256({})", h),
236 Policy::Hash256(ref h) => write!(f, "hash256({})", h),
237 Policy::Ripemd160(ref h) => write!(f, "ripemd160({})", h),
238 Policy::Hash160(ref h) => write!(f, "hash160({})", h),
239 Policy::Thresh(ref thresh) => {
240 if thresh.k() == thresh.n() {
241 thresh.debug("and", false).fmt(f)
242 } else if thresh.k() == 1 {
243 thresh.debug("or", false).fmt(f)
244 } else {
245 thresh.debug("thresh", true).fmt(f)
246 }
247 }
248 }
249 }
250}
251
252impl<Pk: MiniscriptKey> fmt::Display for Policy<Pk> {
253 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
254 match *self {
255 Policy::Unsatisfiable => f.write_str("UNSATISFIABLE"),
256 Policy::Trivial => f.write_str("TRIVIAL"),
257 Policy::Key(ref pkh) => write!(f, "pk({})", pkh),
258 Policy::After(n) => write!(f, "after({})", n),
259 Policy::Older(n) => write!(f, "older({})", n),
260 Policy::Sha256(ref h) => write!(f, "sha256({})", h),
261 Policy::Hash256(ref h) => write!(f, "hash256({})", h),
262 Policy::Ripemd160(ref h) => write!(f, "ripemd160({})", h),
263 Policy::Hash160(ref h) => write!(f, "hash160({})", h),
264 Policy::Thresh(ref thresh) => {
265 if thresh.k() == thresh.n() {
266 thresh.display("and", false).fmt(f)
267 } else if thresh.k() == 1 {
268 thresh.display("or", false).fmt(f)
269 } else {
270 thresh.display("thresh", true).fmt(f)
271 }
272 }
273 }
274 }
275}
276
277impl<Pk: FromStrKey> str::FromStr for Policy<Pk> {
278 type Err = Error;
279 fn from_str(s: &str) -> Result<Policy<Pk>, Error> {
280 expression::check_valid_chars(s)?;
281
282 let tree = expression::Tree::from_str(s)?;
283 expression::FromTree::from_tree(&tree)
284 }
285}
286
287serde_string_impl_pk!(Policy, "a miniscript semantic policy");
288
289impl<Pk: FromStrKey> expression::FromTree for Policy<Pk> {
290 fn from_tree(top: &expression::Tree) -> Result<Policy<Pk>, Error> {
291 match (top.name, top.args.len()) {
292 ("UNSATISFIABLE", 0) => Ok(Policy::Unsatisfiable),
293 ("TRIVIAL", 0) => Ok(Policy::Trivial),
294 ("pk", 1) => expression::terminal(&top.args[0], |pk| Pk::from_str(pk).map(Policy::Key)),
295 ("after", 1) => expression::terminal(&top.args[0], |x| {
296 expression::parse_num(x)
297 .and_then(|x| AbsLockTime::from_consensus(x).map_err(Error::AbsoluteLockTime))
298 .map(Policy::After)
299 }),
300 ("older", 1) => expression::terminal(&top.args[0], |x| {
301 expression::parse_num(x)
302 .and_then(|x| RelLockTime::from_consensus(x).map_err(Error::RelativeLockTime))
303 .map(Policy::Older)
304 }),
305 ("sha256", 1) => {
306 expression::terminal(&top.args[0], |x| Pk::Sha256::from_str(x).map(Policy::Sha256))
307 }
308 ("hash256", 1) => expression::terminal(&top.args[0], |x| {
309 Pk::Hash256::from_str(x).map(Policy::Hash256)
310 }),
311 ("ripemd160", 1) => expression::terminal(&top.args[0], |x| {
312 Pk::Ripemd160::from_str(x).map(Policy::Ripemd160)
313 }),
314 ("hash160", 1) => expression::terminal(&top.args[0], |x| {
315 Pk::Hash160::from_str(x).map(Policy::Hash160)
316 }),
317 ("and", nsubs) => {
318 if nsubs < 2 {
319 return Err(Error::PolicyError(PolicyError::InsufficientArgsforAnd));
320 }
321 let mut subs = Vec::with_capacity(nsubs);
322 for arg in &top.args {
323 subs.push(Arc::new(Policy::from_tree(arg)?));
324 }
325 Ok(Policy::Thresh(Threshold::new(nsubs, subs).map_err(Error::Threshold)?))
326 }
327 ("or", nsubs) => {
328 if nsubs < 2 {
329 return Err(Error::PolicyError(PolicyError::InsufficientArgsforOr));
330 }
331 let mut subs = Vec::with_capacity(nsubs);
332 for arg in &top.args {
333 subs.push(Arc::new(Policy::from_tree(arg)?));
334 }
335 Ok(Policy::Thresh(Threshold::new(1, subs).map_err(Error::Threshold)?))
336 }
337 ("thresh", _) => {
338 let thresh = top.to_null_threshold().map_err(Error::ParseThreshold)?;
339
340 if thresh.is_or() || thresh.is_and() {
342 return Err(errstr(
343 "Semantic Policy thresh cannot have k = 1 or k = n, use `and`/`or` instead",
344 ));
345 }
346
347 thresh
348 .translate_by_index(|i| Policy::from_tree(&top.args[1 + i]).map(Arc::new))
349 .map(Policy::Thresh)
350 }
351 _ => Err(errstr(top.name)),
352 }
353 }
354}
355
356impl<Pk: MiniscriptKey> Policy<Pk> {
357 pub fn normalized(self) -> Policy<Pk> {
360 match self {
361 Policy::Thresh(thresh) => {
362 let mut ret_subs = Vec::with_capacity(thresh.n());
363
364 let subs: Vec<_> = thresh
365 .iter()
366 .map(|sub| Arc::new(sub.as_ref().clone().normalized()))
367 .collect();
368 let trivial_count = subs
369 .iter()
370 .filter(|&pol| *pol.as_ref() == Policy::Trivial)
371 .count();
372 let unsatisfied_count = subs
373 .iter()
374 .filter(|&pol| *pol.as_ref() == Policy::Unsatisfiable)
375 .count();
376
377 let n = subs.len() - unsatisfied_count - trivial_count; let m = thresh.k().saturating_sub(trivial_count); let is_and = m == n;
381 let is_or = m == 1;
382
383 for sub in subs {
384 match sub.as_ref() {
385 Policy::Trivial | Policy::Unsatisfiable => {}
386 Policy::Thresh(ref subthresh) => {
387 match (is_and, is_or) {
388 (true, true) => {
389 ret_subs.push(Arc::new(Policy::Thresh(subthresh.clone())));
391 }
392 (true, false) if subthresh.k() == subthresh.n() => {
393 ret_subs.extend(subthresh.iter().cloned())
394 } (false, true) if subthresh.k() == 1 => {
396 ret_subs.extend(subthresh.iter().cloned())
397 } _ => ret_subs.push(Arc::new(Policy::Thresh(subthresh.clone()))),
399 }
400 }
401 x => ret_subs.push(Arc::new(x.clone())),
402 }
403 }
404 if m == 0 {
406 Policy::Trivial
407 } else if m > ret_subs.len() {
408 Policy::Unsatisfiable
409 } else if ret_subs.len() == 1 {
410 let policy = ret_subs.pop().unwrap();
411 Arc::try_unwrap(policy).unwrap()
413 } else if is_and {
414 Policy::Thresh(Threshold::new(ret_subs.len(), ret_subs).unwrap())
416 } else if is_or {
417 Policy::Thresh(Threshold::new(1, ret_subs).unwrap())
419 } else {
420 Policy::Thresh(Threshold::new(m, ret_subs).unwrap())
422 }
423 }
424 x => x,
425 }
426 }
427
428 pub fn is_trivial(&self) -> bool { matches!(*self, Policy::Trivial) }
434
435 pub fn is_unsatisfiable(&self) -> bool { matches!(*self, Policy::Unsatisfiable) }
441
442 fn real_relative_timelocks(&self) -> Vec<u32> {
444 self.pre_order_iter()
445 .filter_map(|policy| match policy {
446 Policy::Older(t) => Some(t.to_consensus_u32()),
447 _ => None,
448 })
449 .collect()
450 }
451
452 pub fn relative_timelocks(&self) -> Vec<u32> {
455 let mut ret = self.real_relative_timelocks();
456 ret.sort_unstable();
457 ret.dedup();
458 ret
459 }
460
461 fn real_absolute_timelocks(&self) -> Vec<u32> {
463 self.pre_order_iter()
464 .filter_map(|policy| match policy {
465 Policy::After(t) => Some(t.to_consensus_u32()),
466 _ => None,
467 })
468 .collect()
469 }
470
471 pub fn absolute_timelocks(&self) -> Vec<u32> {
474 let mut ret = self.real_absolute_timelocks();
475 ret.sort_unstable();
476 ret.dedup();
477 ret
478 }
479
480 pub fn at_age(self, age: relative::LockTime) -> Policy<Pk> {
483 use Policy::*;
484
485 let mut at_age = vec![];
486 for data in Arc::new(self).post_order_iter() {
487 let new_policy = match data.node.as_ref() {
488 Older(ref t) => {
489 if relative::LockTime::from(*t).is_implied_by(age) {
490 Some(Older(*t))
491 } else {
492 Some(Unsatisfiable)
493 }
494 }
495 Thresh(ref thresh) => {
496 Some(Thresh(thresh.map_from_post_order_iter(&data.child_indices, &at_age)))
497 }
498 _ => None,
499 };
500 match new_policy {
501 Some(new_policy) => at_age.push(Arc::new(new_policy)),
502 None => at_age.push(Arc::clone(&data.node)),
503 }
504 }
505 let root_node = at_age.pop().unwrap();
507 let policy = Arc::try_unwrap(root_node).unwrap();
509 policy.normalized()
510 }
511
512 pub fn at_lock_time(self, n: absolute::LockTime) -> Policy<Pk> {
515 use Policy::*;
516
517 let mut at_age = vec![];
518 for data in Arc::new(self).post_order_iter() {
519 let new_policy = match data.node.as_ref() {
520 After(t) => {
521 if absolute::LockTime::from(*t).is_implied_by(n) {
522 Some(After(*t))
523 } else {
524 Some(Unsatisfiable)
525 }
526 }
527 Thresh(ref thresh) => {
528 Some(Thresh(thresh.map_from_post_order_iter(&data.child_indices, &at_age)))
529 }
530 _ => None,
531 };
532 match new_policy {
533 Some(new_policy) => at_age.push(Arc::new(new_policy)),
534 None => at_age.push(Arc::clone(&data.node)),
535 }
536 }
537 let root_node = at_age.pop().unwrap();
539 let policy = Arc::try_unwrap(root_node).unwrap();
541 policy.normalized()
542 }
543
544 pub fn n_keys(&self) -> usize {
547 self.pre_order_iter()
548 .filter(|policy| matches!(policy, Policy::Key(..)))
549 .count()
550 }
551
552 pub fn minimum_n_keys(&self) -> Option<usize> {
559 use Policy::*;
560
561 let mut minimum_n_keys = vec![];
562 for data in Arc::new(self).post_order_iter() {
563 let minimum_n_keys_for_child_n = |n| minimum_n_keys[data.child_indices[n]];
564
565 let minimum_n_key = match data.node {
566 Unsatisfiable => None,
567 Trivial | After(..) | Older(..) | Sha256(..) | Hash256(..) | Ripemd160(..)
568 | Hash160(..) => Some(0),
569 Key(..) => Some(1),
570 Thresh(ref thresh) => {
571 let mut sublens = (0..thresh.n())
572 .filter_map(minimum_n_keys_for_child_n)
573 .collect::<Vec<usize>>();
574 if sublens.len() < thresh.k() {
575 None
577 } else {
578 sublens.sort_unstable();
579 Some(sublens[0..thresh.k()].iter().cloned().sum::<usize>())
580 }
581 }
582 };
583 minimum_n_keys.push(minimum_n_key);
584 }
585 minimum_n_keys.pop().unwrap()
587 }
588}
589
590impl<Pk: MiniscriptKey> Policy<Pk> {
591 pub fn sorted(self) -> Policy<Pk> {
597 use Policy::*;
598
599 let mut sorted = vec![];
600 for data in Arc::new(self).post_order_iter() {
601 let new_policy = match data.node.as_ref() {
602 Thresh(ref thresh) => {
603 let mut new_thresh =
604 thresh.map_from_post_order_iter(&data.child_indices, &sorted);
605 new_thresh.data_mut().sort();
606 Some(Thresh(new_thresh))
607 }
608 _ => None,
609 };
610 match new_policy {
611 Some(new_policy) => sorted.push(Arc::new(new_policy)),
612 None => sorted.push(Arc::clone(&data.node)),
613 }
614 }
615 let root_node = sorted.pop().unwrap();
617 Arc::try_unwrap(root_node).unwrap()
619 }
620}
621
622impl<Pk: MiniscriptKey> TreeLike for &'_ Policy<Pk> {
623 fn as_node(&self) -> Tree<Self> {
624 use Policy::*;
625
626 match *self {
627 Unsatisfiable | Trivial | Key(_) | After(_) | Older(_) | Sha256(_) | Hash256(_)
628 | Ripemd160(_) | Hash160(_) => Tree::Nullary,
629 Thresh(ref thresh) => Tree::Nary(thresh.iter().map(Arc::as_ref).collect()),
630 }
631 }
632}
633
634impl<Pk: MiniscriptKey> TreeLike for Arc<Policy<Pk>> {
635 fn as_node(&self) -> Tree<Self> {
636 use Policy::*;
637
638 match self.as_ref() {
639 Unsatisfiable | Trivial | Key(_) | After(_) | Older(_) | Sha256(_) | Hash256(_)
640 | Ripemd160(_) | Hash160(_) => Tree::Nullary,
641 Thresh(ref thresh) => Tree::Nary(thresh.iter().map(Arc::clone).collect()),
642 }
643 }
644}
645
646#[cfg(test)]
647mod tests {
648 use bitcoin::PublicKey;
649
650 use super::*;
651
652 type StringPolicy = Policy<String>;
653
654 #[test]
655 fn parse_policy_err() {
656 assert!(StringPolicy::from_str("(").is_err());
657 assert!(StringPolicy::from_str("(x()").is_err());
658 assert!(StringPolicy::from_str("(\u{7f}()3").is_err());
659 assert!(StringPolicy::from_str("pk()").is_ok());
660
661 assert!(StringPolicy::from_str("or(or)").is_err());
662
663 assert!(Policy::<PublicKey>::from_str("pk()").is_err());
664 assert!(Policy::<PublicKey>::from_str(
665 "pk(\
666 0200000000000000000000000000000000000002\
667 )"
668 )
669 .is_err());
670 assert!(Policy::<PublicKey>::from_str(
671 "pk(\
672 02c79ef3ede6d14f72a00d0e49b4becfb152197b64c0707425c4f231df29500ee7\
673 )"
674 )
675 .is_ok());
676 }
677
678 #[test]
679 fn semantic_analysis() {
680 let policy = StringPolicy::from_str("pk()").unwrap();
681 assert_eq!(policy, Policy::Key("".to_owned()));
682 assert_eq!(policy.relative_timelocks(), vec![]);
683 assert_eq!(policy.absolute_timelocks(), vec![]);
684 assert_eq!(policy.clone().at_age(RelLockTime::ZERO.into()), policy);
685 assert_eq!(
686 policy
687 .clone()
688 .at_age(RelLockTime::from_height(10000).into()),
689 policy
690 );
691 assert_eq!(policy.n_keys(), 1);
692 assert_eq!(policy.minimum_n_keys(), Some(1));
693
694 let policy = StringPolicy::from_str("older(1000)").unwrap();
695 assert_eq!(policy, Policy::Older(RelLockTime::from_height(1000)));
696 assert_eq!(policy.absolute_timelocks(), vec![]);
697 assert_eq!(policy.relative_timelocks(), vec![1000]);
698 assert_eq!(policy.clone().at_age(RelLockTime::ZERO.into()), Policy::Unsatisfiable);
699 assert_eq!(
700 policy.clone().at_age(RelLockTime::from_height(999).into()),
701 Policy::Unsatisfiable
702 );
703 assert_eq!(policy.clone().at_age(RelLockTime::from_height(1000).into()), policy);
704 assert_eq!(
705 policy
706 .clone()
707 .at_age(RelLockTime::from_height(10000).into()),
708 policy
709 );
710 assert_eq!(policy.n_keys(), 0);
711 assert_eq!(policy.minimum_n_keys(), Some(0));
712
713 let policy = StringPolicy::from_str("or(pk(),older(1000))").unwrap();
714 assert_eq!(
715 policy,
716 Policy::Thresh(Threshold::or(
717 Policy::Key("".to_owned()).into(),
718 Policy::Older(RelLockTime::from_height(1000)).into(),
719 ))
720 );
721 assert_eq!(policy.relative_timelocks(), vec![1000]);
722 assert_eq!(policy.absolute_timelocks(), vec![]);
723 assert_eq!(policy.clone().at_age(RelLockTime::ZERO.into()), Policy::Key("".to_owned()));
724 assert_eq!(
725 policy.clone().at_age(RelLockTime::from_height(999).into()),
726 Policy::Key("".to_owned())
727 );
728 assert_eq!(
729 policy.clone().at_age(RelLockTime::from_height(1000).into()),
730 policy.clone().normalized()
731 );
732 assert_eq!(
733 policy
734 .clone()
735 .at_age(RelLockTime::from_height(10000).into()),
736 policy.clone().normalized()
737 );
738 assert_eq!(policy.n_keys(), 1);
739 assert_eq!(policy.minimum_n_keys(), Some(0));
740
741 let policy = StringPolicy::from_str("or(pk(),UNSATISFIABLE)").unwrap();
742 assert_eq!(
743 policy,
744 Policy::Thresh(Threshold::or(
745 Policy::Key("".to_owned()).into(),
746 Policy::Unsatisfiable.into()
747 ))
748 );
749 assert_eq!(policy.relative_timelocks(), vec![]);
750 assert_eq!(policy.absolute_timelocks(), vec![]);
751 assert_eq!(policy.n_keys(), 1);
752 assert_eq!(policy.minimum_n_keys(), Some(1));
753
754 let policy = StringPolicy::from_str("and(pk(),UNSATISFIABLE)").unwrap();
755 assert_eq!(
756 policy,
757 Policy::Thresh(Threshold::and(
758 Policy::Key("".to_owned()).into(),
759 Policy::Unsatisfiable.into()
760 ))
761 );
762 assert_eq!(policy.relative_timelocks(), vec![]);
763 assert_eq!(policy.absolute_timelocks(), vec![]);
764 assert_eq!(policy.n_keys(), 1);
765 assert_eq!(policy.minimum_n_keys(), None);
766
767 let policy = StringPolicy::from_str(
768 "thresh(\
769 2,older(1000),older(10000),older(1000),older(2000),older(2000)\
770 )",
771 )
772 .unwrap();
773 assert_eq!(
774 policy,
775 Policy::Thresh(
776 Threshold::new(
777 2,
778 vec![
779 Policy::Older(RelLockTime::from_height(1000)).into(),
780 Policy::Older(RelLockTime::from_height(10000)).into(),
781 Policy::Older(RelLockTime::from_height(1000)).into(),
782 Policy::Older(RelLockTime::from_height(2000)).into(),
783 Policy::Older(RelLockTime::from_height(2000)).into(),
784 ]
785 )
786 .unwrap()
787 )
788 );
789 assert_eq!(
790 policy.relative_timelocks(),
791 vec![1000, 2000, 10000] );
793
794 let policy = StringPolicy::from_str(
795 "thresh(\
796 2,older(1000),older(10000),older(1000),UNSATISFIABLE,UNSATISFIABLE\
797 )",
798 )
799 .unwrap();
800 assert_eq!(
801 policy,
802 Policy::Thresh(
803 Threshold::new(
804 2,
805 vec![
806 Policy::Older(RelLockTime::from_height(1000)).into(),
807 Policy::Older(RelLockTime::from_height(10000)).into(),
808 Policy::Older(RelLockTime::from_height(1000)).into(),
809 Policy::Unsatisfiable.into(),
810 Policy::Unsatisfiable.into(),
811 ]
812 )
813 .unwrap()
814 )
815 );
816 assert_eq!(
817 policy.relative_timelocks(),
818 vec![1000, 10000] );
820 assert_eq!(policy.n_keys(), 0);
821 assert_eq!(policy.minimum_n_keys(), Some(0));
822
823 let policy = StringPolicy::from_str("after(1000)").unwrap();
825 assert_eq!(policy, Policy::After(AbsLockTime::from_consensus(1000).unwrap()));
826 assert_eq!(policy.absolute_timelocks(), vec![1000]);
827 assert_eq!(policy.relative_timelocks(), vec![]);
828 assert_eq!(policy.clone().at_lock_time(absolute::LockTime::ZERO), Policy::Unsatisfiable);
829 assert_eq!(
830 policy
831 .clone()
832 .at_lock_time(absolute::LockTime::from_height(999).expect("valid block height")),
833 Policy::Unsatisfiable
834 );
835 assert_eq!(
836 policy
837 .clone()
838 .at_lock_time(absolute::LockTime::from_height(1000).expect("valid block height")),
839 policy
840 );
841 assert_eq!(
842 policy
843 .clone()
844 .at_lock_time(absolute::LockTime::from_height(10000).expect("valid block height")),
845 policy
846 );
847 assert_eq!(
849 policy
850 .clone()
851 .at_lock_time(absolute::LockTime::from_time(500_000_001).expect("valid timestamp")),
852 Policy::Unsatisfiable
853 );
854 assert_eq!(policy.n_keys(), 0);
855 assert_eq!(policy.minimum_n_keys(), Some(0));
856
857 let policy = StringPolicy::from_str("after(500000010)").unwrap();
859 assert_eq!(policy, Policy::After(AbsLockTime::from_consensus(500_000_010).unwrap()));
860 assert_eq!(policy.absolute_timelocks(), vec![500_000_010]);
861 assert_eq!(policy.relative_timelocks(), vec![]);
862 assert_eq!(policy.clone().at_lock_time(absolute::LockTime::ZERO), Policy::Unsatisfiable);
864 assert_eq!(
865 policy
866 .clone()
867 .at_lock_time(absolute::LockTime::from_height(999).expect("valid block height")),
868 Policy::Unsatisfiable
869 );
870 assert_eq!(
871 policy
872 .clone()
873 .at_lock_time(absolute::LockTime::from_height(1000).expect("valid block height")),
874 Policy::Unsatisfiable
875 );
876 assert_eq!(
877 policy
878 .clone()
879 .at_lock_time(absolute::LockTime::from_height(10000).expect("valid block height")),
880 Policy::Unsatisfiable
881 );
882 assert_eq!(
884 policy
885 .clone()
886 .at_lock_time(absolute::LockTime::from_time(500_000_000).expect("valid timestamp")),
887 Policy::Unsatisfiable
888 );
889 assert_eq!(
890 policy
891 .clone()
892 .at_lock_time(absolute::LockTime::from_time(500_000_001).expect("valid timestamp")),
893 Policy::Unsatisfiable
894 );
895 assert_eq!(
896 policy
897 .clone()
898 .at_lock_time(absolute::LockTime::from_time(500_000_010).expect("valid timestamp")),
899 policy
900 );
901 assert_eq!(
902 policy
903 .clone()
904 .at_lock_time(absolute::LockTime::from_time(500_000_012).expect("valid timestamp")),
905 policy
906 );
907 assert_eq!(policy.n_keys(), 0);
908 assert_eq!(policy.minimum_n_keys(), Some(0));
909 }
910
911 #[test]
912 fn entailment_liquid_test() {
913 let liquid_pol = StringPolicy::from_str(
915 "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();
916 let master_key = StringPolicy::from_str("and(older(50000000),pk(master))").unwrap();
918 let new_liquid_pol =
919 Policy::Thresh(Threshold::or(liquid_pol.clone().into(), master_key.into()));
920
921 assert!(liquid_pol.clone().entails(new_liquid_pol.clone()).unwrap());
922 assert!(!new_liquid_pol.entails(liquid_pol.clone()).unwrap());
923
924 let backup_policy = StringPolicy::from_str("thresh(2,pk(A),pk(B),pk(C))").unwrap();
926 assert!(!backup_policy
927 .entails(
928 liquid_pol
929 .clone()
930 .at_age(RelLockTime::from_height(4095).into())
931 )
932 .unwrap());
933
934 let fed_pol = StringPolicy::from_str("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();
936 let backup_policy_after_expiry =
937 StringPolicy::from_str("and(older(4096),thresh(2,pk(A),pk(B),pk(C)))").unwrap();
938 assert!(fed_pol.entails(liquid_pol.clone()).unwrap());
939 assert!(backup_policy_after_expiry.entails(liquid_pol).unwrap());
940 }
941
942 #[test]
943 fn entailment_escrow() {
944 let escrow_pol = StringPolicy::from_str("thresh(2,pk(Alice),pk(Bob),pk(Judge))").unwrap();
946 let auth_alice = StringPolicy::from_str("and(pk(Alice),pk(Judge))").unwrap();
950
951 let control_alice = StringPolicy::from_str("or(pk(Alice),and(pk(Judge),pk(Bob)))").unwrap();
956
957 assert!(auth_alice.entails(escrow_pol.clone()).unwrap());
960 assert!(escrow_pol.entails(control_alice).unwrap());
961
962 let h = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
965 let htlc_pol = StringPolicy::from_str(&format!(
966 "or(and(pk(Alice),older(100)),and(pk(Bob),sha256({})))",
967 h
968 ))
969 .unwrap();
970 let auth_alice = StringPolicy::from_str("and(pk(Alice),older(100))").unwrap();
975
976 let control_alice =
981 StringPolicy::from_str(&format!("or(pk(Alice),sha256({}))", h)).unwrap();
982
983 assert!(auth_alice.entails(htlc_pol.clone()).unwrap());
986 assert!(htlc_pol.entails(control_alice).unwrap());
987 }
988
989 #[test]
990 fn for_each_key() {
991 let liquid_pol = StringPolicy::from_str(
992 "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();
993 let mut count = 0;
994 assert!(liquid_pol.for_each_key(|_| {
995 count += 1;
996 true
997 }));
998 assert_eq!(count, 17);
999 }
1000}