bells_miniscript/policy/
semantic.rs

1// Written in 2019 by Andrew Poelstra <apoelstra@wpsoftware.net>
2// SPDX-License-Identifier: CC0-1.0
3
4//! Abstract Policies
5
6use 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/// Abstract policy which corresponds to the semantics of a Miniscript
17/// and which allows complex forms of analysis, e.g. filtering and
18/// normalization.
19/// Semantic policies store only hashes of keys to ensure that objects
20/// representing the same policy are lifted to the same `Semantic`,
21/// regardless of their choice of `pk` or `pk_h` nodes.
22#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
23pub enum Policy<Pk: MiniscriptKey> {
24    /// Unsatisfiable
25    Unsatisfiable,
26    /// Trivially satisfiable
27    Trivial,
28    /// Signature and public key matching a given hash is required
29    Key(Pk),
30    /// An absolute locktime restriction
31    After(AbsLockTime),
32    /// A relative locktime restriction
33    Older(Sequence),
34    /// A SHA256 whose preimage must be provided to satisfy the descriptor
35    Sha256(Pk::Sha256),
36    /// A SHA256d whose preimage must be provided to satisfy the descriptor
37    Hash256(Pk::Hash256),
38    /// A RIPEMD160 whose preimage must be provided to satisfy the descriptor
39    Ripemd160(Pk::Ripemd160),
40    /// A HASH160 whose preimage must be provided to satisfy the descriptor
41    Hash160(Pk::Hash160),
42    /// A set of descriptors, satisfactions must be provided for `k` of them
43    Threshold(usize, Vec<Policy<Pk>>),
44}
45
46impl<Pk> Policy<Pk>
47where
48    Pk: MiniscriptKey,
49{
50    /// Construct a `Policy::After` from `n`. Helper function equivalent to
51    /// `Policy::After(absolute::LockTime::from_consensus(n))`.
52    pub fn after(n: u32) -> Policy<Pk> {
53        Policy::After(AbsLockTime::from(absolute::LockTime::from_consensus(n)))
54    }
55
56    /// Construct a `Policy::Older` from `n`. Helper function equivalent to
57    /// `Policy::Older(Sequence::from_consensus(n))`.
58    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    /// Convert a policy using one kind of public key to another
87    /// type of public key
88    ///
89    /// # Example
90    ///
91    /// ```
92    /// use miniscript::{bellscoin::{hashes::hash160, PublicKey}, policy::semantic::Policy, Translator};
93    /// use miniscript::translate_hash_fail;
94    /// use std::str::FromStr;
95    /// use std::collections::HashMap;
96    /// let alice_pk = "02c79ef3ede6d14f72a00d0e49b4becfb152197b64c0707425c4f231df29500ee7";
97    /// let bob_pk = "03d008a849fbf474bd17e9d2c1a827077a468150e58221582ec3410ab309f5afe4";
98    /// let placeholder_policy = Policy::<String>::from_str("and(pk(alice_pk),pk(bob_pk))").unwrap();
99    ///
100    /// // Information to translator abstract String type keys to concrete bellscoin::PublicKey.
101    /// // In practice, wallets would map from String key names to BIP32 keys
102    /// struct StrPkTranslator {
103    ///     pk_map: HashMap<String, bellscoin::PublicKey>
104    /// }
105    ///
106    /// // If we also wanted to provide mapping of other associated types(sha256, older etc),
107    /// // we would use the general Translator Trait.
108    /// impl Translator<String, bellscoin::PublicKey, ()> for StrPkTranslator {
109    ///     fn pk(&mut self, pk: &String) -> Result<bellscoin::PublicKey, ()> {
110    ///         self.pk_map.get(pk).copied().ok_or(()) // Dummy Err
111    ///     }
112    ///
113    ///    // Handy macro for failing if we encounter any other fragment.
114    ///    // also see translate_hash_clone! for cloning instead of failing
115    ///     translate_hash_fail!(String, bellscoin::PublicKey, ());
116    /// }
117    ///
118    /// let mut pk_map = HashMap::new();
119    /// pk_map.insert(String::from("alice_pk"), bellscoin::PublicKey::from_str(alice_pk).unwrap());
120    /// pk_map.insert(String::from("bob_pk"), bellscoin::PublicKey::from_str(bob_pk).unwrap());
121    /// let mut t = StrPkTranslator { pk_map: pk_map };
122    ///
123    /// let real_policy = placeholder_policy.translate_pk(&mut t).unwrap();
124    ///
125    /// let expected_policy = Policy::from_str(&format!("and(pk({}),pk({}))", alice_pk, bob_pk)).unwrap();
126    /// assert_eq!(real_policy, expected_policy);
127    /// ```
128    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    /// This function computes whether the current policy entails the second one.
160    /// A |- B means every satisfaction of A is also a satisfaction of B.
161    /// This implementation will run slow for larger policies but should be sufficient for
162    /// most practical policies.
163
164    // This algorithm has a naive implementation. It is possible to optimize this
165    // by memoizing and maintaining a hashmap.
166    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    // Helper function to compute the number of constraints in policy.
192    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    // Helper function to get the first constraint in the policy.
201    // Returns the first leaf policy. Used in policy entailment.
202    // Assumes that the current policy is normalized.
203    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    // Helper function that takes in witness and its availability,
212    // changing it to true or false and returning the resultant normalized
213    // policy.
214    // Witness is currently encoded as policy. Only accepts leaf fragment and
215    // a normalized policy
216    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            // We can't debug_assert on Policy::Threshold.
220            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                    // thresh() and thresh(k) are err
375                    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                // thresh(1) and thresh(n) are disallowed in semantic policies
384                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    /// Flatten out trees of `And`s and `Or`s; eliminate `Trivial` and
406    /// `Unsatisfiable`s. Does not reorder any branches; use `.sort`.
407    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; // remove all true/false
420                let m = k.checked_sub(trivial_count).map_or(0, |x| x); // satisfy all trivial
421                                                                       // m == n denotes `and` and m == 1 denotes `or`
422                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                                    // means m = n = 1, thresh(1,X) type thing.
431                                    ret_subs.push(Policy::Threshold(k, subs));
432                                }
433                                (true, false) if k == subs.len() => ret_subs.extend(subs), // and case
434                                (false, true) if k == 1 => ret_subs.extend(subs), // or case
435                                _ => ret_subs.push(Policy::Threshold(k, subs)),
436                            }
437                        }
438                        x => ret_subs.push(x),
439                    }
440                }
441                // Now reason about m of n threshold
442                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    /// Helper function to detect a true/trivial policy
461    /// This function only checks whether the policy is Policy::Trivial
462    /// For checking if the normalized form is trivial, the caller
463    /// is expected to normalize the policy first.
464    pub fn is_trivial(&self) -> bool {
465        match *self {
466            Policy::Trivial => true,
467            _ => false,
468        }
469    }
470
471    /// Helper function to detect a false/unsatisfiable policy
472    /// This function only checks whether the policy is Policy::Unsatisfiable
473    /// For checking if the normalized form is unsatisfiable, the caller
474    /// is expected to normalize the policy first.
475    pub fn is_unsatisfiable(&self) -> bool {
476        match *self {
477            Policy::Unsatisfiable => true,
478            _ => false,
479        }
480    }
481
482    /// Helper function to do the recursion in `timelocks`.
483    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    /// Returns a list of all relative timelocks, not including 0,
502    /// which appear in the policy
503    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    /// Helper function for recursion in `absolute timelocks`
511    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    /// Returns a list of all absolute timelocks, not including 0,
530    /// which appear in the policy
531    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    /// Filter a policy by eliminating relative timelock constraints
539    /// that are not satisfied at the given `age`.
540    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    /// Filter a policy by eliminating absolute timelock constraints
561    /// that are not satisfied at the given `n` (`n OP_CHECKLOCKTIMEVERIFY`).
562    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    /// Count the number of public keys and keyhashes referenced in a policy.
588    /// Duplicate keys will be double-counted.
589    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    /// Count the minimum number of public keys for which signatures
604    /// could be used to satisfy the policy.
605    /// Returns `None` if the policy is not satisfiable.
606    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                    // Not enough branches are satisfiable
622                    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    /// "Sort" a policy to bring it into a canonical form to allow comparisons.
634    /// Does **not** allow policies to be compared for functional equivalence;
635    /// in general this appears to require Gröbner basis techniques that are not
636    /// implemented.
637    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] //sorted and dedup'd
782        );
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] //sorted and dedup'd
806        );
807        assert_eq!(policy.n_keys(), 0);
808        assert_eq!(policy.minimum_n_keys(), Some(0));
809
810        // Block height 1000.
811        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        // Pass a UNIX timestamp to at_lock_time while policy uses a block height.
838        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        // UNIX timestamp of 10 seconds after the epoch.
848        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        // Pass a block height to at_lock_time while policy uses a UNIX timestapm.
853        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        // And now pass a UNIX timestamp to at_lock_time while policy also uses a timestamp.
876        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        //liquid policy
907        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        // Very bad idea to add master key,pk but let's have it have 50M blocks
910        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        // test liquid backup policy before the emergency timeout
917        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        // Finally test both spending paths
923        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        // Escrow contract
933        let escrow_pol = StringPolicy::from_str("thresh(2,pk(Alice),pk(Bob),pk(Judge))").unwrap();
934        // Alice's authorization constraint
935        // Authorization is a constraint that states the conditions under which one party must
936        // be able to redeem the funds.
937        let auth_alice = StringPolicy::from_str("and(pk(Alice),pk(Judge))").unwrap();
938
939        //Alice's Control constraint
940        // The control constraint states the conditions that one party requires
941        // must be met if the funds are spent by anyone
942        // Either Alice must authorize the funds or both Judge and Bob must control it
943        let control_alice = StringPolicy::from_str("or(pk(Alice),and(pk(Judge),pk(Bob)))").unwrap();
944
945        // Entailment rules
946        // Authorization entails |- policy |- control constraints
947        assert!(auth_alice.entails(escrow_pol.clone()).unwrap());
948        assert!(escrow_pol.entails(control_alice).unwrap());
949
950        // Entailment HTLC's
951        // Escrow contract
952        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        // Alice's authorization constraint
959        // Authorization is a constraint that states the conditions under which one party must
960        // be able to redeem the funds. In HLTC, alice only cares that she can
961        // authorize her funds with Pk and CSV 100.
962        let auth_alice = StringPolicy::from_str("and(pk(Alice),older(100))").unwrap();
963
964        //Alice's Control constraint
965        // The control constraint states the conditions that one party requires
966        // must be met if the funds are spent by anyone
967        // Either Alice must authorize the funds or sha2 preimage must be revealed.
968        let control_alice =
969            StringPolicy::from_str(&format!("or(pk(Alice),sha256({}))", h)).unwrap();
970
971        // Entailment rules
972        // Authorization entails |- policy |- control constraints
973        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}