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