1use std::str::FromStr;
7use std::{fmt, str};
8
9use bitcoin_miniscript::expression::check_valid_chars;
10use elements::{LockTime, Sequence};
11
12use super::concrete::PolicyError;
13use super::ENTAILMENT_MAX_TERMINALS;
14use crate::{errstr, expression, AbsLockTime, Error, MiniscriptKey, Translator};
15
16#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
23pub enum Policy<Pk: MiniscriptKey> {
24 Unsatisfiable,
26 Trivial,
28 Key(Pk),
30 After(AbsLockTime),
32 Older(Sequence),
34 Sha256(Pk::Sha256),
36 Hash256(Pk::Hash256),
38 Ripemd160(Pk::Ripemd160),
40 Hash160(Pk::Hash160),
42 Threshold(usize, Vec<Policy<Pk>>),
44}
45
46impl<Pk> Policy<Pk>
47where
48 Pk: MiniscriptKey,
49{
50 pub fn after(n: u32) -> Policy<Pk> {
53 Policy::After(AbsLockTime::from(LockTime::from_consensus(n)))
54 }
55
56 pub fn older(n: u32) -> Policy<Pk> {
59 Policy::Older(Sequence::from_consensus(n))
60 }
61}
62
63impl<Pk: MiniscriptKey> Policy<Pk> {
64 pub fn translate_pk<Q, E, T>(&self, t: &mut T) -> Result<Policy<Q>, E>
107 where
108 T: Translator<Pk, Q, E>,
109 Q: MiniscriptKey,
110 {
111 self._translate_pk(t)
112 }
113
114 fn _translate_pk<Q, E, T>(&self, t: &mut T) -> Result<Policy<Q>, E>
115 where
116 T: Translator<Pk, Q, E>,
117 Q: MiniscriptKey,
118 {
119 match *self {
120 Policy::Unsatisfiable => Ok(Policy::Unsatisfiable),
121 Policy::Trivial => Ok(Policy::Trivial),
122 Policy::Key(ref pk) => t.pk(pk).map(Policy::Key),
123 Policy::Sha256(ref h) => t.sha256(h).map(Policy::Sha256),
124 Policy::Hash256(ref h) => t.hash256(h).map(Policy::Hash256),
125 Policy::Ripemd160(ref h) => t.ripemd160(h).map(Policy::Ripemd160),
126 Policy::Hash160(ref h) => t.hash160(h).map(Policy::Hash160),
127 Policy::After(n) => Ok(Policy::After(n)),
128 Policy::Older(n) => Ok(Policy::Older(n)),
129 Policy::Threshold(k, ref subs) => {
130 let new_subs: Result<Vec<Policy<Q>>, _> =
131 subs.iter().map(|sub| sub._translate_pk(t)).collect();
132 new_subs.map(|ok| Policy::Threshold(k, ok))
133 }
134 }
135 }
136
137 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 match self {
171 &Policy::Threshold(_k, ref subs) => subs.iter().map(|sub| sub.n_terminals()).sum(),
172 &Policy::Trivial | &Policy::Unsatisfiable => 0,
173 _leaf => 1,
174 }
175 }
176
177 fn first_constraint(&self) -> Policy<Pk> {
181 debug_assert!(self.clone().normalized() == self.clone());
182 match self {
183 &Policy::Threshold(_k, ref subs) => subs[0].first_constraint(),
184 first => first.clone(),
185 }
186 }
187
188 pub(crate) fn satisfy_constraint(self, witness: &Policy<Pk>, available: bool) -> Policy<Pk> {
194 debug_assert!(self.clone().normalized() == self);
195 if let Policy::Threshold { .. } = *witness {
197 unreachable!()
198 }
199 let ret = match self {
200 Policy::Threshold(k, subs) => {
201 let mut ret_subs = vec![];
202 for sub in subs {
203 ret_subs.push(sub.satisfy_constraint(witness, available));
204 }
205 Policy::Threshold(k, ret_subs)
206 }
207 ref leaf if leaf == witness => {
208 if available {
209 Policy::Trivial
210 } else {
211 Policy::Unsatisfiable
212 }
213 }
214 x => x,
215 };
216 ret.normalized()
217 }
218}
219
220impl<Pk: MiniscriptKey> fmt::Debug for Policy<Pk> {
221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222 match *self {
223 Policy::Unsatisfiable => f.write_str("UNSATISFIABLE()"),
224 Policy::Trivial => f.write_str("TRIVIAL()"),
225 Policy::Key(ref pkh) => write!(f, "pk({:?})", pkh),
226 Policy::After(n) => write!(f, "after({})", n),
227 Policy::Older(n) => write!(f, "older({})", n),
228 Policy::Sha256(ref h) => write!(f, "sha256({})", h),
229 Policy::Hash256(ref h) => write!(f, "hash256({})", h),
230 Policy::Ripemd160(ref h) => write!(f, "ripemd160({})", h),
231 Policy::Hash160(ref h) => write!(f, "hash160({})", h),
232 Policy::Threshold(k, ref subs) => {
233 if k == subs.len() {
234 write!(f, "and(")?;
235 } else if k == 1 {
236 write!(f, "or(")?;
237 } else {
238 write!(f, "thresh({},", k)?;
239 }
240 for (i, sub) in subs.iter().enumerate() {
241 if i == 0 {
242 write!(f, "{}", sub)?;
243 } else {
244 write!(f, ",{}", sub)?;
245 }
246 }
247 f.write_str(")")
248 }
249 }
250 }
251}
252
253impl<Pk: MiniscriptKey> fmt::Display for Policy<Pk> {
254 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
255 match *self {
256 Policy::Unsatisfiable => f.write_str("UNSATISFIABLE"),
257 Policy::Trivial => f.write_str("TRIVIAL"),
258 Policy::Key(ref pkh) => write!(f, "pk({})", pkh),
259 Policy::After(n) => write!(f, "after({})", n),
260 Policy::Older(n) => write!(f, "older({})", n),
261 Policy::Sha256(ref h) => write!(f, "sha256({})", h),
262 Policy::Hash256(ref h) => write!(f, "hash256({})", h),
263 Policy::Ripemd160(ref h) => write!(f, "ripemd160({})", h),
264 Policy::Hash160(ref h) => write!(f, "hash160({})", h),
265 Policy::Threshold(k, ref subs) => {
266 if k == subs.len() {
267 write!(f, "and(")?;
268 } else if k == 1 {
269 write!(f, "or(")?;
270 } else {
271 write!(f, "thresh({},", k)?;
272 }
273 for (i, sub) in subs.iter().enumerate() {
274 if i == 0 {
275 write!(f, "{}", sub)?;
276 } else {
277 write!(f, ",{}", sub)?;
278 }
279 }
280 f.write_str(")")
281 }
282 }
283 }
284}
285
286impl_from_str!(
287 Policy<Pk>,
288 type Err = Error;,
289 fn from_str(s: &str) -> Result<Policy<Pk>, Error> {
290 check_valid_chars(s)?;
291
292 let tree = expression::Tree::from_str(s)?;
293 expression::FromTree::from_tree(&tree)
294 }
295);
296
297serde_string_impl_pk!(Policy, "a miniscript semantic policy");
298
299impl_from_tree!(
300 Policy<Pk>,
301 fn from_tree(top: &expression::Tree) -> Result<Policy<Pk>, Error> {
302 match (top.name, top.args.len()) {
303 ("UNSATISFIABLE", 0) => Ok(Policy::Unsatisfiable),
304 ("TRIVIAL", 0) => Ok(Policy::Trivial),
305 ("pk", 1) => expression::terminal(&top.args[0], |pk| Pk::from_str(pk).map(Policy::Key)),
306 ("after", 1) => expression::terminal(&top.args[0], |x| {
307 expression::parse_num::<u32>(x).map(|x| Policy::after(x))
308 }),
309 ("older", 1) => expression::terminal(&top.args[0], |x| {
310 expression::parse_num::<u32>(x).map(|x| Policy::older(x))
311 }),
312 ("sha256", 1) => expression::terminal(&top.args[0], |x| {
313 Pk::Sha256::from_str(x).map(Policy::Sha256)
314 }),
315 ("hash256", 1) => expression::terminal(&top.args[0], |x| {
316 Pk::Hash256::from_str(x).map(Policy::Hash256)
317 }),
318 ("ripemd160", 1) => expression::terminal(&top.args[0], |x| {
319 Pk::Ripemd160::from_str(x).map(Policy::Ripemd160)
320 }),
321 ("hash160", 1) => expression::terminal(&top.args[0], |x| {
322 Pk::Hash160::from_str(x).map(Policy::Hash160)
323 }),
324 ("and", nsubs) => {
325 if nsubs < 2 {
326 return Err(Error::PolicyError(PolicyError::InsufficientArgsforAnd));
327 }
328 let mut subs = Vec::with_capacity(nsubs);
329 for arg in &top.args {
330 subs.push(Policy::from_tree(arg)?);
331 }
332 Ok(Policy::Threshold(nsubs, subs))
333 }
334 ("or", nsubs) => {
335 if nsubs < 2 {
336 return Err(Error::PolicyError(PolicyError::InsufficientArgsforOr));
337 }
338 let mut subs = Vec::with_capacity(nsubs);
339 for arg in &top.args {
340 subs.push(Policy::from_tree(arg)?);
341 }
342 Ok(Policy::Threshold(1, subs))
343 }
344 ("thresh", nsubs) => {
345 if nsubs == 0 || nsubs == 1 {
346 return Err(errstr("thresh without args"));
348 }
349 if !top.args[0].args.is_empty() {
350 return Err(errstr(top.args[0].args[0].name));
351 }
352
353 let thresh = expression::parse_num::<u32>(top.args[0].name)?;
354
355 if thresh <= 1 || thresh >= (nsubs as u32 - 1) {
357 return Err(errstr(
358 "Semantic Policy thresh cannot have k = 1 or k =n, use `and`/`or` instead",
359 ));
360 }
361 if thresh >= (nsubs as u32) {
362 return Err(errstr(top.args[0].name));
363 }
364
365 let mut subs = Vec::with_capacity(top.args.len() - 1);
366 for arg in &top.args[1..] {
367 subs.push(Policy::from_tree(arg)?);
368 }
369 Ok(Policy::Threshold(thresh as usize, subs))
370 }
371 _ => Err(errstr(top.name)),
372 }
373 }
374);
375
376impl<Pk: MiniscriptKey> Policy<Pk> {
377 pub fn normalized(self) -> Policy<Pk> {
380 match self {
381 Policy::Threshold(k, subs) => {
382 let mut ret_subs = Vec::with_capacity(subs.len());
383
384 let subs: Vec<_> = subs.into_iter().map(|sub| sub.normalized()).collect();
385 let trivial_count = subs.iter().filter(|&pol| *pol == Policy::Trivial).count();
386 let unsatisfied_count = subs
387 .iter()
388 .filter(|&pol| *pol == Policy::Unsatisfiable)
389 .count();
390
391 let n = subs.len() - unsatisfied_count - trivial_count; let m = k.checked_sub(trivial_count).map_or(0, |x| x); let is_and = m == n;
395 let is_or = m == 1;
396 for sub in subs {
397 match sub {
398 Policy::Trivial | Policy::Unsatisfiable => {}
399 Policy::Threshold(k, subs) => {
400 match (is_and, is_or) {
401 (true, true) => {
402 ret_subs.push(Policy::Threshold(k, subs));
404 }
405 (true, false) if k == subs.len() => ret_subs.extend(subs), (false, true) if k == 1 => ret_subs.extend(subs), _ => ret_subs.push(Policy::Threshold(k, subs)),
408 }
409 }
410 x => ret_subs.push(x),
411 }
412 }
413 if m == 0 {
415 Policy::Trivial
416 } else if m > ret_subs.len() {
417 Policy::Unsatisfiable
418 } else if ret_subs.len() == 1 {
419 ret_subs.pop().unwrap()
420 } else if is_and {
421 Policy::Threshold(ret_subs.len(), ret_subs)
422 } else if is_or {
423 Policy::Threshold(1, ret_subs)
424 } else {
425 Policy::Threshold(m, ret_subs)
426 }
427 }
428 x => x,
429 }
430 }
431
432 pub fn is_trivial(&self) -> bool {
437 matches!(*self, Policy::Trivial)
438 }
439
440 pub fn is_unsatisfiable(&self) -> bool {
445 matches!(*self, Policy::Unsatisfiable)
446 }
447
448 fn real_relative_timelocks(&self) -> Vec<u32> {
450 match *self {
451 Policy::Unsatisfiable
452 | Policy::Trivial
453 | Policy::Key(..)
454 | Policy::Sha256(..)
455 | Policy::Hash256(..)
456 | Policy::Ripemd160(..)
457 | Policy::Hash160(..) => vec![],
458 Policy::After(..) => vec![],
459 Policy::Older(t) => vec![t.to_consensus_u32()],
460 Policy::Threshold(_, ref subs) => subs.iter().fold(vec![], |mut acc, x| {
461 acc.extend(x.real_relative_timelocks());
462 acc
463 }),
464 }
465 }
466
467 pub fn relative_timelocks(&self) -> Vec<u32> {
470 let mut ret = self.real_relative_timelocks();
471 ret.sort_unstable();
472 ret.dedup();
473 ret
474 }
475
476 fn real_absolute_timelocks(&self) -> Vec<u32> {
478 match *self {
479 Policy::Unsatisfiable
480 | Policy::Trivial
481 | Policy::Key(..)
482 | Policy::Sha256(..)
483 | Policy::Hash256(..)
484 | Policy::Ripemd160(..)
485 | Policy::Hash160(..) => vec![],
486 Policy::Older(..) => vec![],
487 Policy::After(t) => vec![t.to_u32()],
488 Policy::Threshold(_, ref subs) => subs.iter().fold(vec![], |mut acc, x| {
489 acc.extend(x.real_absolute_timelocks());
490 acc
491 }),
492 }
493 }
494
495 pub fn absolute_timelocks(&self) -> Vec<u32> {
498 let mut ret = self.real_absolute_timelocks();
499 ret.sort_unstable();
500 ret.dedup();
501 ret
502 }
503
504 pub fn at_age(mut self, age: Sequence) -> Policy<Pk> {
507 self = match self {
508 Policy::Older(t) => {
509 if t.is_height_locked() && age.is_time_locked()
510 || t.is_time_locked() && age.is_height_locked()
511 || t.to_consensus_u32() > age.to_consensus_u32()
512 {
513 Policy::Unsatisfiable
514 } else {
515 Policy::Older(t)
516 }
517 }
518 Policy::Threshold(k, subs) => {
519 Policy::Threshold(k, subs.into_iter().map(|sub| sub.at_age(age)).collect())
520 }
521 x => x,
522 };
523 self.normalized()
524 }
525
526 pub fn at_lock_time(mut self, n: LockTime) -> Policy<Pk> {
529 use LockTime::*;
530
531 self = match self {
532 Policy::After(t) => {
533 let t = LockTime::from(t);
534 let is_satisfied_by = match (t, n) {
535 (Blocks(t), Blocks(n)) => t <= n,
536 (Seconds(t), Seconds(n)) => t <= n,
537 _ => false,
538 };
539 if !is_satisfied_by {
540 Policy::Unsatisfiable
541 } else {
542 Policy::After(t.into())
543 }
544 }
545 Policy::Threshold(k, subs) => {
546 Policy::Threshold(k, subs.into_iter().map(|sub| sub.at_lock_time(n)).collect())
547 }
548 x => x,
549 };
550 self.normalized()
551 }
552
553 pub fn n_keys(&self) -> usize {
556 match *self {
557 Policy::Unsatisfiable | Policy::Trivial => 0,
558 Policy::Key(..) => 1,
559 Policy::After(..)
560 | Policy::Older(..)
561 | Policy::Sha256(..)
562 | Policy::Hash256(..)
563 | Policy::Ripemd160(..)
564 | Policy::Hash160(..) => 0,
565 Policy::Threshold(_, ref subs) => subs.iter().map(|sub| sub.n_keys()).sum::<usize>(),
566 }
567 }
568
569 pub fn minimum_n_keys(&self) -> Option<usize> {
573 match *self {
574 Policy::Unsatisfiable => None,
575 Policy::Trivial => Some(0),
576 Policy::Key(..) => Some(1),
577 Policy::After(..)
578 | Policy::Older(..)
579 | Policy::Sha256(..)
580 | Policy::Hash256(..)
581 | Policy::Ripemd160(..)
582 | Policy::Hash160(..) => Some(0),
583 Policy::Threshold(k, ref subs) => {
584 let mut sublens: Vec<usize> =
585 subs.iter().filter_map(Policy::minimum_n_keys).collect();
586 if sublens.len() < k {
587 None
589 } else {
590 sublens.sort_unstable();
591 Some(sublens[0..k].iter().cloned().sum::<usize>())
592 }
593 }
594 }
595 }
596}
597
598impl<Pk: MiniscriptKey> Policy<Pk> {
599 pub fn sorted(self) -> Policy<Pk> {
604 match self {
605 Policy::Threshold(k, subs) => {
606 let mut new_subs: Vec<_> = subs.into_iter().map(Policy::sorted).collect();
607 new_subs.sort();
608 Policy::Threshold(k, new_subs)
609 }
610 x => x,
611 }
612 }
613}
614
615#[cfg(test)]
616mod tests {
617 use std::str::FromStr;
618
619 use bitcoin::PublicKey;
620
621 use super::*;
622
623 type StringPolicy = Policy<String>;
624
625 #[test]
626 fn parse_policy_err() {
627 assert!(StringPolicy::from_str("(").is_err());
628 assert!(StringPolicy::from_str("(x()").is_err());
629 assert!(StringPolicy::from_str("(\u{7f}()3").is_err());
630 assert!(StringPolicy::from_str("pk()").is_ok());
631
632 assert!(StringPolicy::from_str("or(or)").is_err());
633
634 assert!(Policy::<PublicKey>::from_str("pk()").is_err());
635 assert!(Policy::<PublicKey>::from_str(
636 "pk(\
637 0200000000000000000000000000000000000002\
638 )"
639 )
640 .is_err());
641 assert!(Policy::<PublicKey>::from_str(
642 "pk(\
643 02c79ef3ede6d14f72a00d0e49b4becfb152197b64c0707425c4f231df29500ee7\
644 )"
645 )
646 .is_ok());
647 }
648
649 #[test]
650 fn semantic_analysis() {
651 let policy = StringPolicy::from_str("pk()").unwrap();
652 assert_eq!(policy, Policy::Key("".to_owned()));
653 assert!(policy.relative_timelocks().is_empty());
654 assert!(policy.absolute_timelocks().is_empty());
655 assert_eq!(policy.clone().at_age(Sequence::ZERO), policy);
656 assert_eq!(policy.clone().at_age(Sequence::from_height(10000)), policy);
657 assert_eq!(policy.n_keys(), 1);
658 assert_eq!(policy.minimum_n_keys(), Some(1));
659
660 let policy = StringPolicy::from_str("older(1000)").unwrap();
661 assert_eq!(policy, Policy::Older(Sequence::from_height(1000)));
662 assert!(policy.absolute_timelocks().is_empty());
663 assert_eq!(policy.relative_timelocks(), vec![1000]);
664 assert_eq!(policy.clone().at_age(Sequence::ZERO), Policy::Unsatisfiable);
665 assert_eq!(
666 policy.clone().at_age(Sequence::from_height(999)),
667 Policy::Unsatisfiable
668 );
669 assert_eq!(policy.clone().at_age(Sequence::from_height(1000)), policy);
670 assert_eq!(policy.clone().at_age(Sequence::from_height(10000)), policy);
671 assert_eq!(policy.n_keys(), 0);
672 assert_eq!(policy.minimum_n_keys(), Some(0));
673
674 let policy = StringPolicy::from_str("or(pk(),older(1000))").unwrap();
675 assert_eq!(
676 policy,
677 Policy::Threshold(
678 1,
679 vec![
680 Policy::Key("".to_owned()),
681 Policy::Older(Sequence::from_height(1000)),
682 ]
683 )
684 );
685 assert_eq!(policy.relative_timelocks(), vec![1000]);
686 assert!(policy.absolute_timelocks().is_empty());
687 assert_eq!(
688 policy.clone().at_age(Sequence::ZERO),
689 Policy::Key("".to_owned())
690 );
691 assert_eq!(
692 policy.clone().at_age(Sequence::from_height(999)),
693 Policy::Key("".to_owned())
694 );
695 assert_eq!(
696 policy.clone().at_age(Sequence::from_height(1000)),
697 policy.clone().normalized()
698 );
699 assert_eq!(
700 policy.clone().at_age(Sequence::from_height(10000)),
701 policy.clone().normalized()
702 );
703 assert_eq!(policy.n_keys(), 1);
704 assert_eq!(policy.minimum_n_keys(), Some(0));
705
706 let policy = StringPolicy::from_str("or(pk(),UNSATISFIABLE)").unwrap();
707 assert_eq!(
708 policy,
709 Policy::Threshold(1, vec![Policy::Key("".to_owned()), Policy::Unsatisfiable,])
710 );
711 assert_eq!(policy.relative_timelocks().len(), 0);
712 assert_eq!(policy.absolute_timelocks().len(), 0);
713 assert_eq!(policy.n_keys(), 1);
714 assert_eq!(policy.minimum_n_keys(), Some(1));
715
716 let policy = StringPolicy::from_str("and(pk(),UNSATISFIABLE)").unwrap();
717 assert_eq!(
718 policy,
719 Policy::Threshold(2, vec![Policy::Key("".to_owned()), Policy::Unsatisfiable,])
720 );
721 assert_eq!(policy.relative_timelocks().len(), 0);
722 assert_eq!(policy.absolute_timelocks().len(), 0);
723 assert_eq!(policy.n_keys(), 1);
724 assert_eq!(policy.minimum_n_keys(), None);
725
726 let policy = StringPolicy::from_str(
727 "thresh(\
728 2,older(1000),older(10000),older(1000),older(2000),older(2000)\
729 )",
730 )
731 .unwrap();
732 assert_eq!(
733 policy,
734 Policy::Threshold(
735 2,
736 vec![
737 Policy::Older(Sequence::from_height(1000)),
738 Policy::Older(Sequence::from_height(10000)),
739 Policy::Older(Sequence::from_height(1000)),
740 Policy::Older(Sequence::from_height(2000)),
741 Policy::Older(Sequence::from_height(2000)),
742 ]
743 )
744 );
745 assert_eq!(
746 policy.relative_timelocks(),
747 vec![1000, 2000, 10000] );
749
750 let policy = StringPolicy::from_str(
751 "thresh(\
752 2,older(1000),older(10000),older(1000),UNSATISFIABLE,UNSATISFIABLE\
753 )",
754 )
755 .unwrap();
756 assert_eq!(
757 policy,
758 Policy::Threshold(
759 2,
760 vec![
761 Policy::Older(Sequence::from_height(1000)),
762 Policy::Older(Sequence::from_height(10000)),
763 Policy::Older(Sequence::from_height(1000)),
764 Policy::Unsatisfiable,
765 Policy::Unsatisfiable,
766 ]
767 )
768 );
769 assert_eq!(
770 policy.relative_timelocks(),
771 vec![1000, 10000] );
773 assert_eq!(policy.n_keys(), 0);
774 assert_eq!(policy.minimum_n_keys(), Some(0));
775
776 let policy = StringPolicy::from_str("after(1000)").unwrap();
778 assert_eq!(policy, Policy::after(1000));
779 assert_eq!(policy.absolute_timelocks(), vec![1000]);
780 assert!(policy.relative_timelocks().is_empty());
781 assert_eq!(
782 policy.clone().at_lock_time(LockTime::ZERO),
783 Policy::Unsatisfiable
784 );
785 assert_eq!(
786 policy
787 .clone()
788 .at_lock_time(LockTime::from_height(999).expect("valid block height")),
789 Policy::Unsatisfiable
790 );
791 assert_eq!(
792 policy
793 .clone()
794 .at_lock_time(LockTime::from_height(1000).expect("valid block height")),
795 policy
796 );
797 assert_eq!(
798 policy
799 .clone()
800 .at_lock_time(LockTime::from_height(10000).expect("valid block height")),
801 policy
802 );
803 assert_eq!(
805 policy
806 .clone()
807 .at_lock_time(LockTime::from_time(500_000_001).expect("valid timestamp")),
808 Policy::Unsatisfiable
809 );
810 assert_eq!(policy.n_keys(), 0);
811 assert_eq!(policy.minimum_n_keys(), Some(0));
812
813 let policy = StringPolicy::from_str("after(500000010)").unwrap();
815 assert_eq!(policy, Policy::after(500_000_010));
816 assert_eq!(policy.absolute_timelocks(), vec![500_000_010]);
817 assert!(policy.relative_timelocks().is_empty());
818 assert_eq!(
820 policy.clone().at_lock_time(LockTime::ZERO),
821 Policy::Unsatisfiable
822 );
823 assert_eq!(
824 policy
825 .clone()
826 .at_lock_time(LockTime::from_height(999).expect("valid block height")),
827 Policy::Unsatisfiable
828 );
829 assert_eq!(
830 policy
831 .clone()
832 .at_lock_time(LockTime::from_height(1000).expect("valid block height")),
833 Policy::Unsatisfiable
834 );
835 assert_eq!(
836 policy
837 .clone()
838 .at_lock_time(LockTime::from_height(10000).expect("valid block height")),
839 Policy::Unsatisfiable
840 );
841 assert_eq!(
843 policy
844 .clone()
845 .at_lock_time(LockTime::from_time(500_000_000).expect("valid timestamp")),
846 Policy::Unsatisfiable
847 );
848 assert_eq!(
849 policy
850 .clone()
851 .at_lock_time(LockTime::from_time(500_000_001).expect("valid timestamp")),
852 Policy::Unsatisfiable
853 );
854 assert_eq!(
855 policy
856 .clone()
857 .at_lock_time(LockTime::from_time(500_000_010).expect("valid timestamp")),
858 policy
859 );
860 assert_eq!(
861 policy
862 .clone()
863 .at_lock_time(LockTime::from_time(500_000_012).expect("valid timestamp")),
864 policy
865 );
866 assert_eq!(policy.n_keys(), 0);
867 assert_eq!(policy.minimum_n_keys(), Some(0));
868 }
869
870 #[test]
871 fn entailment_liquid_test() {
872 let liquid_pol = StringPolicy::from_str(
874 "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();
875 let master_key = StringPolicy::from_str("and(older(50000000),pk(master))").unwrap();
877 let new_liquid_pol = Policy::Threshold(1, vec![liquid_pol.clone(), master_key]);
878
879 assert!(liquid_pol.clone().entails(new_liquid_pol.clone()).unwrap());
880 assert!(!new_liquid_pol.entails(liquid_pol.clone()).unwrap());
881
882 let backup_policy = StringPolicy::from_str("thresh(2,pk(A),pk(B),pk(C))").unwrap();
884 assert!(!backup_policy
885 .entails(liquid_pol.clone().at_age(Sequence::from_height(4095)))
886 .unwrap());
887
888 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();
890 let backup_policy_after_expiry =
891 StringPolicy::from_str("and(older(4096),thresh(2,pk(A),pk(B),pk(C)))").unwrap();
892 assert!(fed_pol.entails(liquid_pol.clone()).unwrap());
893 assert!(backup_policy_after_expiry.entails(liquid_pol).unwrap());
894 }
895
896 #[test]
897 fn entailment_escrow() {
898 let escrow_pol = StringPolicy::from_str("thresh(2,pk(Alice),pk(Bob),pk(Judge))").unwrap();
900 let auth_alice = StringPolicy::from_str("and(pk(Alice),pk(Judge))").unwrap();
904
905 let control_alice = StringPolicy::from_str("or(pk(Alice),and(pk(Judge),pk(Bob)))").unwrap();
910
911 assert!(auth_alice.entails(escrow_pol.clone()).unwrap());
914 assert!(escrow_pol.entails(control_alice).unwrap());
915
916 let h = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
919 let htlc_pol = StringPolicy::from_str(&format!(
920 "or(and(pk(Alice),older(100)),and(pk(Bob),sha256({})))",
921 h
922 ))
923 .unwrap();
924 let auth_alice = StringPolicy::from_str("and(pk(Alice),older(100))").unwrap();
929
930 let control_alice =
935 StringPolicy::from_str(&format!("or(pk(Alice),sha256({}))", h)).unwrap();
936
937 assert!(auth_alice.entails(htlc_pol.clone()).unwrap());
940 assert!(htlc_pol.entails(control_alice).unwrap());
941 }
942}