1use core::str::FromStr;
7use core::{fmt, str};
8
9use bellscoin::{absolute, Sequence};
10
11use super::concrete::PolicyError;
12use super::ENTAILMENT_MAX_TERMINALS;
13use crate::prelude::*;
14use crate::{errstr, expression, AbsLockTime, Error, ForEachKey, 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(absolute::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> ForEachKey<Pk> for Policy<Pk> {
64 fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
65 self.real_for_each_key(&mut pred)
66 }
67}
68
69impl<Pk: MiniscriptKey> Policy<Pk> {
70 fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool {
71 match *self {
72 Policy::Unsatisfiable | Policy::Trivial => true,
73 Policy::Key(ref pk) => pred(pk),
74 Policy::Sha256(..)
75 | Policy::Hash256(..)
76 | Policy::Ripemd160(..)
77 | Policy::Hash160(..)
78 | Policy::After(..)
79 | Policy::Older(..) => true,
80 Policy::Threshold(_, ref subs) => {
81 subs.iter().all(|sub| sub.real_for_each_key(&mut *pred))
82 }
83 }
84 }
85
86 pub fn translate_pk<Q, E, T>(&self, t: &mut T) -> Result<Policy<Q>, E>
129 where
130 T: Translator<Pk, Q, E>,
131 Q: MiniscriptKey,
132 {
133 self._translate_pk(t)
134 }
135
136 fn _translate_pk<Q, E, T>(&self, t: &mut T) -> Result<Policy<Q>, E>
137 where
138 T: Translator<Pk, Q, E>,
139 Q: MiniscriptKey,
140 {
141 match *self {
142 Policy::Unsatisfiable => Ok(Policy::Unsatisfiable),
143 Policy::Trivial => Ok(Policy::Trivial),
144 Policy::Key(ref pk) => t.pk(pk).map(Policy::Key),
145 Policy::Sha256(ref h) => t.sha256(h).map(Policy::Sha256),
146 Policy::Hash256(ref h) => t.hash256(h).map(Policy::Hash256),
147 Policy::Ripemd160(ref h) => t.ripemd160(h).map(Policy::Ripemd160),
148 Policy::Hash160(ref h) => t.hash160(h).map(Policy::Hash160),
149 Policy::After(n) => Ok(Policy::After(n)),
150 Policy::Older(n) => Ok(Policy::Older(n)),
151 Policy::Threshold(k, ref subs) => {
152 let new_subs: Result<Vec<Policy<Q>>, _> =
153 subs.iter().map(|sub| sub._translate_pk(t)).collect();
154 new_subs.map(|ok| Policy::Threshold(k, ok))
155 }
156 }
157 }
158
159 pub fn entails(self, other: Policy<Pk>) -> Result<bool, PolicyError> {
167 if self.n_terminals() > ENTAILMENT_MAX_TERMINALS {
168 return Err(PolicyError::EntailmentMaxTerminals);
169 }
170 match (self, other) {
171 (Policy::Unsatisfiable, _) => Ok(true),
172 (Policy::Trivial, Policy::Trivial) => Ok(true),
173 (Policy::Trivial, _) => Ok(false),
174 (_, Policy::Unsatisfiable) => Ok(false),
175 (a, b) => {
176 let (a_norm, b_norm) = (a.normalized(), b.normalized());
177 let first_constraint = a_norm.first_constraint();
178 let (a1, b1) = (
179 a_norm.clone().satisfy_constraint(&first_constraint, true),
180 b_norm.clone().satisfy_constraint(&first_constraint, true),
181 );
182 let (a2, b2) = (
183 a_norm.satisfy_constraint(&first_constraint, false),
184 b_norm.satisfy_constraint(&first_constraint, false),
185 );
186 Ok(Policy::entails(a1, b1)? && Policy::entails(a2, b2)?)
187 }
188 }
189 }
190
191 fn n_terminals(&self) -> usize {
193 match self {
194 &Policy::Threshold(_k, ref subs) => subs.iter().map(|sub| sub.n_terminals()).sum(),
195 &Policy::Trivial | &Policy::Unsatisfiable => 0,
196 _leaf => 1,
197 }
198 }
199
200 fn first_constraint(&self) -> Policy<Pk> {
204 debug_assert!(self.clone().normalized() == self.clone());
205 match self {
206 &Policy::Threshold(_k, ref subs) => subs[0].first_constraint(),
207 first => first.clone(),
208 }
209 }
210
211 pub(crate) fn satisfy_constraint(self, witness: &Policy<Pk>, available: bool) -> Policy<Pk> {
217 debug_assert!(self.clone().normalized() == self);
218 if let Policy::Threshold { .. } = *witness {
219 panic!("should be unreachable")
221 }
222
223 let ret = match self {
224 Policy::Threshold(k, subs) => {
225 let mut ret_subs = vec![];
226 for sub in subs {
227 ret_subs.push(sub.satisfy_constraint(witness, available));
228 }
229 Policy::Threshold(k, ret_subs)
230 }
231 ref leaf if leaf == witness => {
232 if available {
233 Policy::Trivial
234 } else {
235 Policy::Unsatisfiable
236 }
237 }
238 x => x,
239 };
240 ret.normalized()
241 }
242}
243
244impl<Pk: MiniscriptKey> fmt::Debug for Policy<Pk> {
245 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
246 match *self {
247 Policy::Unsatisfiable => f.write_str("UNSATISFIABLE()"),
248 Policy::Trivial => f.write_str("TRIVIAL()"),
249 Policy::Key(ref pkh) => write!(f, "pk({:?})", pkh),
250 Policy::After(n) => write!(f, "after({})", n),
251 Policy::Older(n) => write!(f, "older({})", n),
252 Policy::Sha256(ref h) => write!(f, "sha256({})", h),
253 Policy::Hash256(ref h) => write!(f, "hash256({})", h),
254 Policy::Ripemd160(ref h) => write!(f, "ripemd160({})", h),
255 Policy::Hash160(ref h) => write!(f, "hash160({})", h),
256 Policy::Threshold(k, ref subs) => {
257 if k == subs.len() {
258 write!(f, "and(")?;
259 } else if k == 1 {
260 write!(f, "or(")?;
261 } else {
262 write!(f, "thresh({},", k)?;
263 }
264 for (i, sub) in subs.iter().enumerate() {
265 if i == 0 {
266 write!(f, "{}", sub)?;
267 } else {
268 write!(f, ",{}", sub)?;
269 }
270 }
271 f.write_str(")")
272 }
273 }
274 }
275}
276
277impl<Pk: MiniscriptKey> fmt::Display for Policy<Pk> {
278 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
279 match *self {
280 Policy::Unsatisfiable => f.write_str("UNSATISFIABLE"),
281 Policy::Trivial => f.write_str("TRIVIAL"),
282 Policy::Key(ref pkh) => write!(f, "pk({})", pkh),
283 Policy::After(n) => write!(f, "after({})", n),
284 Policy::Older(n) => write!(f, "older({})", n),
285 Policy::Sha256(ref h) => write!(f, "sha256({})", h),
286 Policy::Hash256(ref h) => write!(f, "hash256({})", h),
287 Policy::Ripemd160(ref h) => write!(f, "ripemd160({})", h),
288 Policy::Hash160(ref h) => write!(f, "hash160({})", h),
289 Policy::Threshold(k, ref subs) => {
290 if k == subs.len() {
291 write!(f, "and(")?;
292 } else if k == 1 {
293 write!(f, "or(")?;
294 } else {
295 write!(f, "thresh({},", k)?;
296 }
297 for (i, sub) in subs.iter().enumerate() {
298 if i == 0 {
299 write!(f, "{}", sub)?;
300 } else {
301 write!(f, ",{}", sub)?;
302 }
303 }
304 f.write_str(")")
305 }
306 }
307 }
308}
309
310impl_from_str!(
311 Policy<Pk>,
312 type Err = Error;,
313 fn from_str(s: &str) -> Result<Policy<Pk>, Error> {
314 for ch in s.as_bytes() {
315 if *ch < 20 || *ch > 127 {
316 return Err(Error::Unprintable(*ch));
317 }
318 }
319
320 let tree = expression::Tree::from_str(s)?;
321 expression::FromTree::from_tree(&tree)
322 }
323);
324
325serde_string_impl_pk!(Policy, "a miniscript semantic policy");
326
327impl_from_tree!(
328 Policy<Pk>,
329 fn from_tree(top: &expression::Tree) -> Result<Policy<Pk>, Error> {
330 match (top.name, top.args.len()) {
331 ("UNSATISFIABLE", 0) => Ok(Policy::Unsatisfiable),
332 ("TRIVIAL", 0) => Ok(Policy::Trivial),
333 ("pk", 1) => expression::terminal(&top.args[0], |pk| Pk::from_str(pk).map(Policy::Key)),
334 ("after", 1) => expression::terminal(&top.args[0], |x| {
335 expression::parse_num(x).map(|x| Policy::after(x))
336 }),
337 ("older", 1) => expression::terminal(&top.args[0], |x| {
338 expression::parse_num(x).map(|x| Policy::older(x))
339 }),
340 ("sha256", 1) => expression::terminal(&top.args[0], |x| {
341 Pk::Sha256::from_str(x).map(Policy::Sha256)
342 }),
343 ("hash256", 1) => expression::terminal(&top.args[0], |x| {
344 Pk::Hash256::from_str(x).map(Policy::Hash256)
345 }),
346 ("ripemd160", 1) => expression::terminal(&top.args[0], |x| {
347 Pk::Ripemd160::from_str(x).map(Policy::Ripemd160)
348 }),
349 ("hash160", 1) => expression::terminal(&top.args[0], |x| {
350 Pk::Hash160::from_str(x).map(Policy::Hash160)
351 }),
352 ("and", nsubs) => {
353 if nsubs < 2 {
354 return Err(Error::PolicyError(PolicyError::InsufficientArgsforAnd));
355 }
356 let mut subs = Vec::with_capacity(nsubs);
357 for arg in &top.args {
358 subs.push(Policy::from_tree(arg)?);
359 }
360 Ok(Policy::Threshold(nsubs, subs))
361 }
362 ("or", nsubs) => {
363 if nsubs < 2 {
364 return Err(Error::PolicyError(PolicyError::InsufficientArgsforOr));
365 }
366 let mut subs = Vec::with_capacity(nsubs);
367 for arg in &top.args {
368 subs.push(Policy::from_tree(arg)?);
369 }
370 Ok(Policy::Threshold(1, subs))
371 }
372 ("thresh", nsubs) => {
373 if nsubs == 0 || nsubs == 1 {
374 return Err(errstr("thresh without args"));
376 }
377 if !top.args[0].args.is_empty() {
378 return Err(errstr(top.args[0].args[0].name));
379 }
380
381 let thresh = expression::parse_num(top.args[0].name)?;
382
383 if thresh <= 1 || thresh >= (nsubs as u32 - 1) {
385 return Err(errstr(
386 "Semantic Policy thresh cannot have k = 1 or k =n, use `and`/`or` instead",
387 ));
388 }
389 if thresh >= (nsubs as u32) {
390 return Err(errstr(top.args[0].name));
391 }
392
393 let mut subs = Vec::with_capacity(top.args.len() - 1);
394 for arg in &top.args[1..] {
395 subs.push(Policy::from_tree(arg)?);
396 }
397 Ok(Policy::Threshold(thresh as usize, subs))
398 }
399 _ => Err(errstr(top.name)),
400 }
401 }
402);
403
404impl<Pk: MiniscriptKey> Policy<Pk> {
405 pub fn normalized(self) -> Policy<Pk> {
408 match self {
409 Policy::Threshold(k, subs) => {
410 let mut ret_subs = Vec::with_capacity(subs.len());
411
412 let subs: Vec<_> = subs.into_iter().map(|sub| sub.normalized()).collect();
413 let trivial_count = subs.iter().filter(|&pol| *pol == Policy::Trivial).count();
414 let unsatisfied_count = subs
415 .iter()
416 .filter(|&pol| *pol == Policy::Unsatisfiable)
417 .count();
418
419 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;
423 let is_or = m == 1;
424 for sub in subs {
425 match sub {
426 Policy::Trivial | Policy::Unsatisfiable => {}
427 Policy::Threshold(k, subs) => {
428 match (is_and, is_or) {
429 (true, true) => {
430 ret_subs.push(Policy::Threshold(k, subs));
432 }
433 (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)),
436 }
437 }
438 x => ret_subs.push(x),
439 }
440 }
441 if m == 0 {
443 Policy::Trivial
444 } else if m > ret_subs.len() {
445 Policy::Unsatisfiable
446 } else if ret_subs.len() == 1 {
447 ret_subs.pop().unwrap()
448 } else if is_and {
449 Policy::Threshold(ret_subs.len(), ret_subs)
450 } else if is_or {
451 Policy::Threshold(1, ret_subs)
452 } else {
453 Policy::Threshold(m, ret_subs)
454 }
455 }
456 x => x,
457 }
458 }
459
460 pub fn is_trivial(&self) -> bool {
465 match *self {
466 Policy::Trivial => true,
467 _ => false,
468 }
469 }
470
471 pub fn is_unsatisfiable(&self) -> bool {
476 match *self {
477 Policy::Unsatisfiable => true,
478 _ => false,
479 }
480 }
481
482 fn real_relative_timelocks(&self) -> Vec<u32> {
484 match *self {
485 Policy::Unsatisfiable
486 | Policy::Trivial
487 | Policy::Key(..)
488 | Policy::Sha256(..)
489 | Policy::Hash256(..)
490 | Policy::Ripemd160(..)
491 | Policy::Hash160(..) => vec![],
492 Policy::After(..) => vec![],
493 Policy::Older(t) => vec![t.to_consensus_u32()],
494 Policy::Threshold(_, ref subs) => subs.iter().fold(vec![], |mut acc, x| {
495 acc.extend(x.real_relative_timelocks());
496 acc
497 }),
498 }
499 }
500
501 pub fn relative_timelocks(&self) -> Vec<u32> {
504 let mut ret = self.real_relative_timelocks();
505 ret.sort_unstable();
506 ret.dedup();
507 ret
508 }
509
510 fn real_absolute_timelocks(&self) -> Vec<u32> {
512 match *self {
513 Policy::Unsatisfiable
514 | Policy::Trivial
515 | Policy::Key(..)
516 | Policy::Sha256(..)
517 | Policy::Hash256(..)
518 | Policy::Ripemd160(..)
519 | Policy::Hash160(..) => vec![],
520 Policy::Older(..) => vec![],
521 Policy::After(t) => vec![t.to_u32()],
522 Policy::Threshold(_, ref subs) => subs.iter().fold(vec![], |mut acc, x| {
523 acc.extend(x.real_absolute_timelocks());
524 acc
525 }),
526 }
527 }
528
529 pub fn absolute_timelocks(&self) -> Vec<u32> {
532 let mut ret = self.real_absolute_timelocks();
533 ret.sort_unstable();
534 ret.dedup();
535 ret
536 }
537
538 pub fn at_age(mut self, age: Sequence) -> Policy<Pk> {
541 self = match self {
542 Policy::Older(t) => {
543 if t.is_height_locked() && age.is_time_locked()
544 || t.is_time_locked() && age.is_height_locked()
545 || t.to_consensus_u32() > age.to_consensus_u32()
546 {
547 Policy::Unsatisfiable
548 } else {
549 Policy::Older(t)
550 }
551 }
552 Policy::Threshold(k, subs) => {
553 Policy::Threshold(k, subs.into_iter().map(|sub| sub.at_age(age)).collect())
554 }
555 x => x,
556 };
557 self.normalized()
558 }
559
560 pub fn at_lock_time(mut self, n: absolute::LockTime) -> Policy<Pk> {
563 use absolute::LockTime::*;
564
565 self = match self {
566 Policy::After(t) => {
567 let t = absolute::LockTime::from(t);
568 let is_satisfied_by = match (t, n) {
569 (Blocks(t), Blocks(n)) => t <= n,
570 (Seconds(t), Seconds(n)) => t <= n,
571 _ => false,
572 };
573 if !is_satisfied_by {
574 Policy::Unsatisfiable
575 } else {
576 Policy::After(t.into())
577 }
578 }
579 Policy::Threshold(k, subs) => {
580 Policy::Threshold(k, subs.into_iter().map(|sub| sub.at_lock_time(n)).collect())
581 }
582 x => x,
583 };
584 self.normalized()
585 }
586
587 pub fn n_keys(&self) -> usize {
590 match *self {
591 Policy::Unsatisfiable | Policy::Trivial => 0,
592 Policy::Key(..) => 1,
593 Policy::After(..)
594 | Policy::Older(..)
595 | Policy::Sha256(..)
596 | Policy::Hash256(..)
597 | Policy::Ripemd160(..)
598 | Policy::Hash160(..) => 0,
599 Policy::Threshold(_, ref subs) => subs.iter().map(|sub| sub.n_keys()).sum::<usize>(),
600 }
601 }
602
603 pub fn minimum_n_keys(&self) -> Option<usize> {
607 match *self {
608 Policy::Unsatisfiable => None,
609 Policy::Trivial => Some(0),
610 Policy::Key(..) => Some(1),
611 Policy::After(..)
612 | Policy::Older(..)
613 | Policy::Sha256(..)
614 | Policy::Hash256(..)
615 | Policy::Ripemd160(..)
616 | Policy::Hash160(..) => Some(0),
617 Policy::Threshold(k, ref subs) => {
618 let mut sublens: Vec<usize> =
619 subs.iter().filter_map(Policy::minimum_n_keys).collect();
620 if sublens.len() < k {
621 None
623 } else {
624 sublens.sort_unstable();
625 Some(sublens[0..k].iter().cloned().sum::<usize>())
626 }
627 }
628 }
629 }
630}
631
632impl<Pk: MiniscriptKey> Policy<Pk> {
633 pub fn sorted(self) -> Policy<Pk> {
638 match self {
639 Policy::Threshold(k, subs) => {
640 let mut new_subs: Vec<_> = subs.into_iter().map(Policy::sorted).collect();
641 new_subs.sort();
642 Policy::Threshold(k, new_subs)
643 }
644 x => x,
645 }
646 }
647}
648
649#[cfg(test)]
650mod tests {
651 use core::str::FromStr;
652
653 use bellscoin::PublicKey;
654
655 use super::*;
656
657 type StringPolicy = Policy<String>;
658
659 #[test]
660 fn parse_policy_err() {
661 assert!(StringPolicy::from_str("(").is_err());
662 assert!(StringPolicy::from_str("(x()").is_err());
663 assert!(StringPolicy::from_str("(\u{7f}()3").is_err());
664 assert!(StringPolicy::from_str("pk()").is_ok());
665
666 assert!(StringPolicy::from_str("or(or)").is_err());
667
668 assert!(Policy::<PublicKey>::from_str("pk()").is_err());
669 assert!(Policy::<PublicKey>::from_str(
670 "pk(\
671 0200000000000000000000000000000000000002\
672 )"
673 )
674 .is_err());
675 assert!(Policy::<PublicKey>::from_str(
676 "pk(\
677 02c79ef3ede6d14f72a00d0e49b4becfb152197b64c0707425c4f231df29500ee7\
678 )"
679 )
680 .is_ok());
681 }
682
683 #[test]
684 fn semantic_analysis() {
685 let policy = StringPolicy::from_str("pk()").unwrap();
686 assert_eq!(policy, Policy::Key("".to_owned()));
687 assert_eq!(policy.relative_timelocks(), vec![]);
688 assert_eq!(policy.absolute_timelocks(), vec![]);
689 assert_eq!(policy.clone().at_age(Sequence::ZERO), policy);
690 assert_eq!(policy.clone().at_age(Sequence::from_height(10000)), policy);
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(Sequence::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(Sequence::ZERO), Policy::Unsatisfiable);
699 assert_eq!(
700 policy.clone().at_age(Sequence::from_height(999)),
701 Policy::Unsatisfiable
702 );
703 assert_eq!(policy.clone().at_age(Sequence::from_height(1000)), policy);
704 assert_eq!(policy.clone().at_age(Sequence::from_height(10000)), policy);
705 assert_eq!(policy.n_keys(), 0);
706 assert_eq!(policy.minimum_n_keys(), Some(0));
707
708 let policy = StringPolicy::from_str("or(pk(),older(1000))").unwrap();
709 assert_eq!(
710 policy,
711 Policy::Threshold(
712 1,
713 vec![
714 Policy::Key("".to_owned()),
715 Policy::Older(Sequence::from_height(1000)),
716 ]
717 )
718 );
719 assert_eq!(policy.relative_timelocks(), vec![1000]);
720 assert_eq!(policy.absolute_timelocks(), vec![]);
721 assert_eq!(
722 policy.clone().at_age(Sequence::ZERO),
723 Policy::Key("".to_owned())
724 );
725 assert_eq!(
726 policy.clone().at_age(Sequence::from_height(999)),
727 Policy::Key("".to_owned())
728 );
729 assert_eq!(
730 policy.clone().at_age(Sequence::from_height(1000)),
731 policy.clone().normalized()
732 );
733 assert_eq!(
734 policy.clone().at_age(Sequence::from_height(10000)),
735 policy.clone().normalized()
736 );
737 assert_eq!(policy.n_keys(), 1);
738 assert_eq!(policy.minimum_n_keys(), Some(0));
739
740 let policy = StringPolicy::from_str("or(pk(),UNSATISFIABLE)").unwrap();
741 assert_eq!(
742 policy,
743 Policy::Threshold(1, vec![Policy::Key("".to_owned()), Policy::Unsatisfiable,])
744 );
745 assert_eq!(policy.relative_timelocks(), vec![]);
746 assert_eq!(policy.absolute_timelocks(), vec![]);
747 assert_eq!(policy.n_keys(), 1);
748 assert_eq!(policy.minimum_n_keys(), Some(1));
749
750 let policy = StringPolicy::from_str("and(pk(),UNSATISFIABLE)").unwrap();
751 assert_eq!(
752 policy,
753 Policy::Threshold(2, vec![Policy::Key("".to_owned()), Policy::Unsatisfiable,])
754 );
755 assert_eq!(policy.relative_timelocks(), vec![]);
756 assert_eq!(policy.absolute_timelocks(), vec![]);
757 assert_eq!(policy.n_keys(), 1);
758 assert_eq!(policy.minimum_n_keys(), None);
759
760 let policy = StringPolicy::from_str(
761 "thresh(\
762 2,older(1000),older(10000),older(1000),older(2000),older(2000)\
763 )",
764 )
765 .unwrap();
766 assert_eq!(
767 policy,
768 Policy::Threshold(
769 2,
770 vec![
771 Policy::Older(Sequence::from_height(1000)),
772 Policy::Older(Sequence::from_height(10000)),
773 Policy::Older(Sequence::from_height(1000)),
774 Policy::Older(Sequence::from_height(2000)),
775 Policy::Older(Sequence::from_height(2000)),
776 ]
777 )
778 );
779 assert_eq!(
780 policy.relative_timelocks(),
781 vec![1000, 2000, 10000] );
783
784 let policy = StringPolicy::from_str(
785 "thresh(\
786 2,older(1000),older(10000),older(1000),UNSATISFIABLE,UNSATISFIABLE\
787 )",
788 )
789 .unwrap();
790 assert_eq!(
791 policy,
792 Policy::Threshold(
793 2,
794 vec![
795 Policy::Older(Sequence::from_height(1000)),
796 Policy::Older(Sequence::from_height(10000)),
797 Policy::Older(Sequence::from_height(1000)),
798 Policy::Unsatisfiable,
799 Policy::Unsatisfiable,
800 ]
801 )
802 );
803 assert_eq!(
804 policy.relative_timelocks(),
805 vec![1000, 10000] );
807 assert_eq!(policy.n_keys(), 0);
808 assert_eq!(policy.minimum_n_keys(), Some(0));
809
810 let policy = StringPolicy::from_str("after(1000)").unwrap();
812 assert_eq!(policy, Policy::after(1000));
813 assert_eq!(policy.absolute_timelocks(), vec![1000]);
814 assert_eq!(policy.relative_timelocks(), vec![]);
815 assert_eq!(
816 policy.clone().at_lock_time(absolute::LockTime::ZERO),
817 Policy::Unsatisfiable
818 );
819 assert_eq!(
820 policy
821 .clone()
822 .at_lock_time(absolute::LockTime::from_height(999).expect("valid block height")),
823 Policy::Unsatisfiable
824 );
825 assert_eq!(
826 policy
827 .clone()
828 .at_lock_time(absolute::LockTime::from_height(1000).expect("valid block height")),
829 policy
830 );
831 assert_eq!(
832 policy
833 .clone()
834 .at_lock_time(absolute::LockTime::from_height(10000).expect("valid block height")),
835 policy
836 );
837 assert_eq!(
839 policy
840 .clone()
841 .at_lock_time(absolute::LockTime::from_time(500_000_001).expect("valid timestamp")),
842 Policy::Unsatisfiable
843 );
844 assert_eq!(policy.n_keys(), 0);
845 assert_eq!(policy.minimum_n_keys(), Some(0));
846
847 let policy = StringPolicy::from_str("after(500000010)").unwrap();
849 assert_eq!(policy, Policy::after(500_000_010));
850 assert_eq!(policy.absolute_timelocks(), vec![500_000_010]);
851 assert_eq!(policy.relative_timelocks(), vec![]);
852 assert_eq!(
854 policy.clone().at_lock_time(absolute::LockTime::ZERO),
855 Policy::Unsatisfiable
856 );
857 assert_eq!(
858 policy
859 .clone()
860 .at_lock_time(absolute::LockTime::from_height(999).expect("valid block height")),
861 Policy::Unsatisfiable
862 );
863 assert_eq!(
864 policy
865 .clone()
866 .at_lock_time(absolute::LockTime::from_height(1000).expect("valid block height")),
867 Policy::Unsatisfiable
868 );
869 assert_eq!(
870 policy
871 .clone()
872 .at_lock_time(absolute::LockTime::from_height(10000).expect("valid block height")),
873 Policy::Unsatisfiable
874 );
875 assert_eq!(
877 policy
878 .clone()
879 .at_lock_time(absolute::LockTime::from_time(500_000_000).expect("valid timestamp")),
880 Policy::Unsatisfiable
881 );
882 assert_eq!(
883 policy
884 .clone()
885 .at_lock_time(absolute::LockTime::from_time(500_000_001).expect("valid timestamp")),
886 Policy::Unsatisfiable
887 );
888 assert_eq!(
889 policy
890 .clone()
891 .at_lock_time(absolute::LockTime::from_time(500_000_010).expect("valid timestamp")),
892 policy
893 );
894 assert_eq!(
895 policy
896 .clone()
897 .at_lock_time(absolute::LockTime::from_time(500_000_012).expect("valid timestamp")),
898 policy
899 );
900 assert_eq!(policy.n_keys(), 0);
901 assert_eq!(policy.minimum_n_keys(), Some(0));
902 }
903
904 #[test]
905 fn entailment_liquid_test() {
906 let liquid_pol = StringPolicy::from_str(
908 "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();
909 let master_key = StringPolicy::from_str("and(older(50000000),pk(master))").unwrap();
911 let new_liquid_pol = Policy::Threshold(1, vec![liquid_pol.clone(), master_key]);
912
913 assert!(liquid_pol.clone().entails(new_liquid_pol.clone()).unwrap());
914 assert!(!new_liquid_pol.entails(liquid_pol.clone()).unwrap());
915
916 let backup_policy = StringPolicy::from_str("thresh(2,pk(A),pk(B),pk(C))").unwrap();
918 assert!(!backup_policy
919 .entails(liquid_pol.clone().at_age(Sequence::from_height(4095)))
920 .unwrap());
921
922 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();
924 let backup_policy_after_expiry =
925 StringPolicy::from_str("and(older(4096),thresh(2,pk(A),pk(B),pk(C)))").unwrap();
926 assert!(fed_pol.entails(liquid_pol.clone()).unwrap());
927 assert!(backup_policy_after_expiry.entails(liquid_pol).unwrap());
928 }
929
930 #[test]
931 fn entailment_escrow() {
932 let escrow_pol = StringPolicy::from_str("thresh(2,pk(Alice),pk(Bob),pk(Judge))").unwrap();
934 let auth_alice = StringPolicy::from_str("and(pk(Alice),pk(Judge))").unwrap();
938
939 let control_alice = StringPolicy::from_str("or(pk(Alice),and(pk(Judge),pk(Bob)))").unwrap();
944
945 assert!(auth_alice.entails(escrow_pol.clone()).unwrap());
948 assert!(escrow_pol.entails(control_alice).unwrap());
949
950 let h = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
953 let htlc_pol = StringPolicy::from_str(&format!(
954 "or(and(pk(Alice),older(100)),and(pk(Bob),sha256({})))",
955 h
956 ))
957 .unwrap();
958 let auth_alice = StringPolicy::from_str("and(pk(Alice),older(100))").unwrap();
963
964 let control_alice =
969 StringPolicy::from_str(&format!("or(pk(Alice),sha256({}))", h)).unwrap();
970
971 assert!(auth_alice.entails(htlc_pol.clone()).unwrap());
974 assert!(htlc_pol.entails(control_alice).unwrap());
975 }
976
977 #[test]
978 fn for_each_key() {
979 let liquid_pol = StringPolicy::from_str(
980 "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();
981 let mut count = 0;
982 assert!(liquid_pol.for_each_key(|_| {
983 count += 1;
984 true
985 }));
986 assert_eq!(count, 17);
987 }
988}