bells_miniscript/policy/
concrete.rs

1// Written in 2019 by Andrew Poelstra <apoelstra@wpsoftware.net>
2// SPDX-License-Identifier: CC0-1.0
3
4//! Concrete Policies
5//!
6
7use core::{fmt, str};
8#[cfg(feature = "std")]
9use std::error;
10
11use bellscoin::{absolute, Sequence};
12#[cfg(feature = "compiler")]
13use {
14    crate::descriptor::TapTree,
15    crate::miniscript::ScriptContext,
16    crate::policy::compiler::CompilerError,
17    crate::policy::compiler::OrdF64,
18    crate::policy::{compiler, Concrete, Liftable, Semantic},
19    crate::Descriptor,
20    crate::Miniscript,
21    crate::Tap,
22    core::cmp::Reverse,
23    sync::Arc,
24};
25
26use super::ENTAILMENT_MAX_TERMINALS;
27use crate::expression::{self, FromTree};
28use crate::miniscript::types::extra_props::TimelockInfo;
29use crate::prelude::*;
30#[cfg(all(doc, not(feature = "compiler")))]
31use crate::Descriptor;
32use crate::{errstr, AbsLockTime, Error, ForEachKey, MiniscriptKey, Translator};
33
34/// Maximum TapLeafs allowed in a compiled TapTree
35#[cfg(feature = "compiler")]
36const MAX_COMPILATION_LEAVES: usize = 1024;
37
38/// Concrete policy which corresponds directly to a Miniscript structure,
39/// and whose disjunctions are annotated with satisfaction probabilities
40/// to assist the compiler
41#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
42pub enum Policy<Pk: MiniscriptKey> {
43    /// Unsatisfiable
44    Unsatisfiable,
45    /// Trivially satisfiable
46    Trivial,
47    /// A public key which must sign to satisfy the descriptor
48    Key(Pk),
49    /// An absolute locktime restriction
50    After(AbsLockTime),
51    /// A relative locktime restriction
52    Older(Sequence),
53    /// A SHA256 whose preimage must be provided to satisfy the descriptor
54    Sha256(Pk::Sha256),
55    /// A SHA256d whose preimage must be provided to satisfy the descriptor
56    Hash256(Pk::Hash256),
57    /// A RIPEMD160 whose preimage must be provided to satisfy the descriptor
58    Ripemd160(Pk::Ripemd160),
59    /// A HASH160 whose preimage must be provided to satisfy the descriptor
60    Hash160(Pk::Hash160),
61    /// A list of sub-policies, all of which must be satisfied
62    And(Vec<Policy<Pk>>),
63    /// A list of sub-policies, one of which must be satisfied, along with
64    /// relative probabilities for each one
65    Or(Vec<(usize, Policy<Pk>)>),
66    /// A set of descriptors, satisfactions must be provided for `k` of them
67    Threshold(usize, Vec<Policy<Pk>>),
68}
69
70impl<Pk> Policy<Pk>
71where
72    Pk: MiniscriptKey,
73{
74    /// Construct a `Policy::After` from `n`. Helper function equivalent to
75    /// `Policy::After(absolute::LockTime::from_consensus(n))`.
76    pub fn after(n: u32) -> Policy<Pk> {
77        Policy::After(AbsLockTime::from(absolute::LockTime::from_consensus(n)))
78    }
79
80    /// Construct a `Policy::Older` from `n`. Helper function equivalent to
81    /// `Policy::Older(Sequence::from_consensus(n))`.
82    pub fn older(n: u32) -> Policy<Pk> {
83        Policy::Older(Sequence::from_consensus(n))
84    }
85}
86
87/// Lightweight repr of Concrete policy which corresponds directly to a
88/// Miniscript structure, and whose disjunctions are annotated with satisfaction
89/// probabilities to assist the compiler
90#[cfg(feature = "compiler")]
91#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
92enum PolicyArc<Pk: MiniscriptKey> {
93    /// Unsatisfiable
94    Unsatisfiable,
95    /// Trivially satisfiable
96    Trivial,
97    /// A public key which must sign to satisfy the descriptor
98    Key(Pk),
99    /// An absolute locktime restriction
100    After(AbsLockTime),
101    /// A relative locktime restriction
102    Older(u32),
103    /// A SHA256 whose preimage must be provided to satisfy the descriptor
104    Sha256(Pk::Sha256),
105    /// A SHA256d whose preimage must be provided to satisfy the descriptor
106    Hash256(Pk::Hash256),
107    /// A RIPEMD160 whose preimage must be provided to satisfy the descriptor
108    Ripemd160(Pk::Ripemd160),
109    /// A HASH160 whose preimage must be provided to satisfy the descriptor
110    Hash160(Pk::Hash160),
111    /// A list of sub-policies' references, all of which must be satisfied
112    And(Vec<Arc<PolicyArc<Pk>>>),
113    /// A list of sub-policies's references, one of which must be satisfied,
114    /// along with relative probabilities for each one
115    Or(Vec<(usize, Arc<PolicyArc<Pk>>)>),
116    /// A set of descriptors' references, satisfactions must be provided for `k` of them
117    Threshold(usize, Vec<Arc<PolicyArc<Pk>>>),
118}
119
120#[cfg(feature = "compiler")]
121impl<Pk: MiniscriptKey> From<PolicyArc<Pk>> for Policy<Pk> {
122    fn from(p: PolicyArc<Pk>) -> Self {
123        match p {
124            PolicyArc::Unsatisfiable => Policy::Unsatisfiable,
125            PolicyArc::Trivial => Policy::Trivial,
126            PolicyArc::Key(pk) => Policy::Key(pk),
127            PolicyArc::After(t) => Policy::After(t),
128            PolicyArc::Older(t) => Policy::Older(Sequence::from_consensus(t)),
129            PolicyArc::Sha256(hash) => Policy::Sha256(hash),
130            PolicyArc::Hash256(hash) => Policy::Hash256(hash),
131            PolicyArc::Ripemd160(hash) => Policy::Ripemd160(hash),
132            PolicyArc::Hash160(hash) => Policy::Hash160(hash),
133            PolicyArc::And(subs) => Policy::And(
134                subs.into_iter()
135                    .map(|pol| Self::from((*pol).clone()))
136                    .collect(),
137            ),
138            PolicyArc::Or(subs) => Policy::Or(
139                subs.into_iter()
140                    .map(|(odds, sub)| (odds, Self::from((*sub).clone())))
141                    .collect(),
142            ),
143            PolicyArc::Threshold(k, subs) => Policy::Threshold(
144                k,
145                subs.into_iter()
146                    .map(|pol| Self::from((*pol).clone()))
147                    .collect(),
148            ),
149        }
150    }
151}
152
153#[cfg(feature = "compiler")]
154impl<Pk: MiniscriptKey> From<Policy<Pk>> for PolicyArc<Pk> {
155    fn from(p: Policy<Pk>) -> Self {
156        match p {
157            Policy::Unsatisfiable => PolicyArc::Unsatisfiable,
158            Policy::Trivial => PolicyArc::Trivial,
159            Policy::Key(pk) => PolicyArc::Key(pk),
160            Policy::After(lock_time) => PolicyArc::After(lock_time),
161            Policy::Older(Sequence(t)) => PolicyArc::Older(t),
162            Policy::Sha256(hash) => PolicyArc::Sha256(hash),
163            Policy::Hash256(hash) => PolicyArc::Hash256(hash),
164            Policy::Ripemd160(hash) => PolicyArc::Ripemd160(hash),
165            Policy::Hash160(hash) => PolicyArc::Hash160(hash),
166            Policy::And(subs) => PolicyArc::And(
167                subs.iter()
168                    .map(|sub| Arc::new(Self::from(sub.clone())))
169                    .collect(),
170            ),
171            Policy::Or(subs) => PolicyArc::Or(
172                subs.iter()
173                    .map(|(odds, sub)| (*odds, Arc::new(Self::from(sub.clone()))))
174                    .collect(),
175            ),
176            Policy::Threshold(k, subs) => PolicyArc::Threshold(
177                k,
178                subs.iter()
179                    .map(|sub| Arc::new(Self::from(sub.clone())))
180                    .collect(),
181            ),
182        }
183    }
184}
185
186/// Detailed Error type for Policies
187#[derive(Copy, Clone, PartialEq, Eq, Debug)]
188pub enum PolicyError {
189    /// `And` fragments only support two args
190    NonBinaryArgAnd,
191    /// `Or` fragments only support two args
192    NonBinaryArgOr,
193    /// `Thresh` fragment can only have `1<=k<=n`
194    IncorrectThresh,
195    /// `older` or `after` fragment can only have `n = 0`
196    ZeroTime,
197    /// `after` fragment can only have ` n < 2^31`
198    TimeTooFar,
199    /// Semantic Policy Error: `And` `Or` fragments must take args: k > 1
200    InsufficientArgsforAnd,
201    /// Semantic Policy Error: `And` `Or` fragments must take args: k > 1
202    InsufficientArgsforOr,
203    /// Entailment max terminals exceeded
204    EntailmentMaxTerminals,
205    /// lifting error: Cannot lift policies that have
206    /// a combination of height and timelocks.
207    HeightTimelockCombination,
208    /// Duplicate Public Keys
209    DuplicatePubKeys,
210}
211
212/// Descriptor context for [`Policy`] compilation into a [`Descriptor`].
213pub enum DescriptorCtx<Pk> {
214    /// See docs for [`Descriptor::Bare`].
215    Bare,
216    /// See docs for [`Descriptor::Sh`].
217    Sh,
218    /// See docs for [`Descriptor::Wsh`].
219    Wsh,
220    /// See docs for [`Descriptor::Wsh`].
221    ShWsh,
222    /// [`Descriptor::Tr`] where the `Option<Pk>` corresponds to the internal key if no
223    /// internal key can be inferred from the given policy.
224    Tr(Option<Pk>),
225}
226
227impl fmt::Display for PolicyError {
228    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
229        match *self {
230            PolicyError::NonBinaryArgAnd => {
231                f.write_str("And policy fragment must take 2 arguments")
232            }
233            PolicyError::NonBinaryArgOr => f.write_str("Or policy fragment must take 2 arguments"),
234            PolicyError::IncorrectThresh => {
235                f.write_str("Threshold k must be greater than 0 and less than or equal to n 0<k<=n")
236            }
237            PolicyError::TimeTooFar => {
238                f.write_str("Relative/Absolute time must be less than 2^31; n < 2^31")
239            }
240            PolicyError::ZeroTime => f.write_str("Time must be greater than 0; n > 0"),
241            PolicyError::InsufficientArgsforAnd => {
242                f.write_str("Semantic Policy 'And' fragment must have at least 2 args ")
243            }
244            PolicyError::InsufficientArgsforOr => {
245                f.write_str("Semantic Policy 'Or' fragment must have at least 2 args ")
246            }
247            PolicyError::EntailmentMaxTerminals => write!(
248                f,
249                "Policy entailment only supports {} terminals",
250                ENTAILMENT_MAX_TERMINALS
251            ),
252            PolicyError::HeightTimelockCombination => {
253                f.write_str("Cannot lift policies that have a heightlock and timelock combination")
254            }
255            PolicyError::DuplicatePubKeys => f.write_str("Policy contains duplicate keys"),
256        }
257    }
258}
259
260#[cfg(feature = "std")]
261impl error::Error for PolicyError {
262    fn cause(&self) -> Option<&dyn error::Error> {
263        use self::PolicyError::*;
264
265        match self {
266            NonBinaryArgAnd
267            | NonBinaryArgOr
268            | IncorrectThresh
269            | ZeroTime
270            | TimeTooFar
271            | InsufficientArgsforAnd
272            | InsufficientArgsforOr
273            | EntailmentMaxTerminals
274            | HeightTimelockCombination
275            | DuplicatePubKeys => None,
276        }
277    }
278}
279
280impl<Pk: MiniscriptKey> Policy<Pk> {
281    /// Flatten the [`Policy`] tree structure into a Vector of tuple `(leaf script, leaf probability)`
282    /// with leaf probabilities corresponding to odds for sub-branch in the policy.
283    /// We calculate the probability of selecting the sub-branch at every level and calculate the
284    /// leaf probabilities as the probability of traversing through required branches to reach the
285    /// leaf node, i.e. multiplication of the respective probabilities.
286    ///
287    /// For example, the policy tree:       OR
288    ///                                   /   \
289    ///                                  2     1            odds
290    ///                                /        \
291    ///                               A         OR
292    ///                                        /  \
293    ///                                       3    1        odds
294    ///                                     /       \
295    ///                                    B         C
296    ///
297    /// gives the vector [(2/3, A), (1/3 * 3/4, B), (1/3 * 1/4, C)].
298    ///
299    /// ## Constraints
300    ///
301    /// Since this splitting might lead to exponential blow-up, we constraint the number of
302    /// leaf-nodes to [`MAX_COMPILATION_LEAVES`].
303    #[cfg(feature = "compiler")]
304    fn to_tapleaf_prob_vec(&self, prob: f64) -> Vec<(f64, Policy<Pk>)> {
305        match self {
306            Policy::Or(ref subs) => {
307                let total_odds: usize = subs.iter().map(|(ref k, _)| k).sum();
308                subs.iter()
309                    .map(|(k, ref policy)| {
310                        policy.to_tapleaf_prob_vec(prob * *k as f64 / total_odds as f64)
311                    })
312                    .flatten()
313                    .collect::<Vec<_>>()
314            }
315            Policy::Threshold(k, ref subs) if *k == 1 => {
316                let total_odds = subs.len();
317                subs.iter()
318                    .map(|policy| policy.to_tapleaf_prob_vec(prob / total_odds as f64))
319                    .flatten()
320                    .collect::<Vec<_>>()
321            }
322            x => vec![(prob, x.clone())],
323        }
324    }
325
326    /// Extract the internal_key from policy tree.
327    #[cfg(feature = "compiler")]
328    fn extract_key(self, unspendable_key: Option<Pk>) -> Result<(Pk, Policy<Pk>), Error> {
329        let mut internal_key: Option<Pk> = None;
330        {
331            let mut prob = 0.;
332            let semantic_policy = self.lift()?;
333            let concrete_keys = self.keys();
334            let key_prob_map: HashMap<_, _> = self
335                .to_tapleaf_prob_vec(1.0)
336                .into_iter()
337                .filter(|(_, ref pol)| match *pol {
338                    Concrete::Key(..) => true,
339                    _ => false,
340                })
341                .map(|(prob, key)| (key, prob))
342                .collect();
343
344            for key in concrete_keys.into_iter() {
345                if semantic_policy
346                    .clone()
347                    .satisfy_constraint(&Semantic::Key(key.clone()), true)
348                    == Semantic::Trivial
349                {
350                    match key_prob_map.get(&Concrete::Key(key.clone())) {
351                        Some(val) => {
352                            if *val > prob {
353                                prob = *val;
354                                internal_key = Some(key.clone());
355                            }
356                        }
357                        None => return Err(errstr("Key should have existed in the HashMap!")),
358                    }
359                }
360            }
361        }
362        match (internal_key, unspendable_key) {
363            (Some(ref key), _) => Ok((key.clone(), self.translate_unsatisfiable_pk(&key))),
364            (_, Some(key)) => Ok((key, self)),
365            _ => Err(errstr("No viable internal key found.")),
366        }
367    }
368
369    /// Compile the [`Policy`] into a [`Descriptor::Tr`].
370    ///
371    /// ### TapTree compilation
372    ///
373    /// The policy tree constructed by root-level disjunctions over [`Or`][`Policy::Or`] and
374    /// [`Thresh`][`Policy::Threshold`](1, ..) which is flattened into a vector (with respective
375    /// probabilities derived from odds) of policies.
376    /// For example, the policy `thresh(1,or(pk(A),pk(B)),and(or(pk(C),pk(D)),pk(E)))` gives the
377    /// vector `[pk(A),pk(B),and(or(pk(C),pk(D)),pk(E)))]`. Each policy in the vector is compiled
378    /// into the respective miniscripts. A Huffman Tree is created from this vector which optimizes
379    /// over the probabilitity of satisfaction for the respective branch in the TapTree.
380    ///
381    /// Refer to [this link](https://gist.github.com/SarcasticNastik/9e70b2b43375aab3e78c51e09c288c89)
382    /// or [doc/Tr compiler.pdf] in the root of the repository to understand why such compilation
383    /// is also *cost-efficient*.
384    // TODO: We might require other compile errors for Taproot.
385    #[cfg(feature = "compiler")]
386    pub fn compile_tr(&self, unspendable_key: Option<Pk>) -> Result<Descriptor<Pk>, Error> {
387        self.is_valid()?; // Check for validity
388        match self.is_safe_nonmalleable() {
389            (false, _) => Err(Error::from(CompilerError::TopLevelNonSafe)),
390            (_, false) => Err(Error::from(
391                CompilerError::ImpossibleNonMalleableCompilation,
392            )),
393            _ => {
394                let (internal_key, policy) = self.clone().extract_key(unspendable_key)?;
395                policy.check_num_tapleaves()?;
396                let tree = Descriptor::new_tr(
397                    internal_key,
398                    match policy {
399                        Policy::Trivial => None,
400                        policy => {
401                            let vec_policies: Vec<_> = policy.to_tapleaf_prob_vec(1.0);
402                            let mut leaf_compilations: Vec<(OrdF64, Miniscript<Pk, Tap>)> = vec![];
403                            for (prob, pol) in vec_policies {
404                                // policy corresponding to the key (replaced by unsatisfiable) is skipped
405                                if pol == Policy::Unsatisfiable {
406                                    continue;
407                                }
408                                let compilation = compiler::best_compilation::<Pk, Tap>(&pol)?;
409                                compilation.sanity_check()?;
410                                leaf_compilations.push((OrdF64(prob), compilation));
411                            }
412                            let taptree = with_huffman_tree::<Pk>(leaf_compilations)?;
413                            Some(taptree)
414                        }
415                    },
416                )?;
417                Ok(tree)
418            }
419        }
420    }
421
422    /// Compiles the [`Policy`] into a [`Descriptor::Tr`].
423    ///
424    /// ### TapTree compilation
425    ///
426    /// The policy tree constructed by root-level disjunctions over [`Policy::Or`] and
427    /// [`Policy::Threshold`] (k, ..n..) which is flattened into a vector (with respective
428    /// probabilities derived from odds) of policies. For example, the policy
429    /// `thresh(1,or(pk(A),pk(B)),and(or(pk(C),pk(D)),pk(E)))` gives the vector
430    /// `[pk(A),pk(B),and(or(pk(C),pk(D)),pk(E)))]`.
431    ///
432    /// ### Policy enumeration
433    ///
434    /// Generates a root-level disjunctive tree over the given policy tree.
435    ///
436    /// Uses a fixed-point algorithm to enumerate the disjunctions until exhaustive root-level
437    /// enumeration or limits exceed. For a given [`Policy`], we maintain an [ordered
438    /// set](`BTreeSet`) of `(prob, policy)` (ordered by probability) to maintain the list of
439    /// enumerated sub-policies whose disjunction is isomorphic to initial policy (*invariant*).
440    ///
441    /// [`Policy`]: crate::policy::concrete::Policy
442    #[cfg(feature = "compiler")]
443    pub fn compile_tr_private_experimental(
444        &self,
445        unspendable_key: Option<Pk>,
446    ) -> Result<Descriptor<Pk>, Error> {
447        self.is_valid()?; // Check for validity
448        match self.is_safe_nonmalleable() {
449            (false, _) => Err(Error::from(CompilerError::TopLevelNonSafe)),
450            (_, false) => Err(Error::from(
451                CompilerError::ImpossibleNonMalleableCompilation,
452            )),
453            _ => {
454                let (internal_key, policy) = self.clone().extract_key(unspendable_key)?;
455                let tree = Descriptor::new_tr(
456                    internal_key,
457                    match policy {
458                        Policy::Trivial => None,
459                        policy => {
460                            let pol = PolicyArc::from(policy);
461                            let leaf_compilations: Vec<_> = pol
462                                .enumerate_policy_tree(1.0)
463                                .into_iter()
464                                .filter(|x| x.1 != Arc::new(PolicyArc::Unsatisfiable))
465                                .map(|(prob, ref pol)| {
466                                    let converted_pol = Policy::<Pk>::from((**pol).clone());
467                                    (
468                                        OrdF64(prob),
469                                        compiler::best_compilation(&converted_pol).unwrap(),
470                                    )
471                                })
472                                .collect();
473                            let taptree = with_huffman_tree::<Pk>(leaf_compilations).unwrap();
474                            Some(taptree)
475                        }
476                    },
477                )?;
478                Ok(tree)
479            }
480        }
481    }
482
483    /// Compile the [`Policy`] into desc_ctx [`Descriptor`]
484    ///
485    /// In case of [Tr][`DescriptorCtx::Tr`], `internal_key` is used for the Taproot comilation when
486    /// no public key can be inferred from the given policy.
487    ///
488    /// # NOTE:
489    ///
490    /// It is **not recommended** to use policy as a stable identifier for a miniscript.
491    /// You should use the policy compiler once, and then use the miniscript output as a stable identifier.
492    /// See the compiler document in doc/compiler.md for more details.
493    #[cfg(feature = "compiler")]
494    pub fn compile_to_descriptor<Ctx: ScriptContext>(
495        &self,
496        desc_ctx: DescriptorCtx<Pk>,
497    ) -> Result<Descriptor<Pk>, Error> {
498        self.is_valid()?;
499        match self.is_safe_nonmalleable() {
500            (false, _) => Err(Error::from(CompilerError::TopLevelNonSafe)),
501            (_, false) => Err(Error::from(
502                CompilerError::ImpossibleNonMalleableCompilation,
503            )),
504            _ => match desc_ctx {
505                DescriptorCtx::Bare => Descriptor::new_bare(compiler::best_compilation(self)?),
506                DescriptorCtx::Sh => Descriptor::new_sh(compiler::best_compilation(self)?),
507                DescriptorCtx::Wsh => Descriptor::new_wsh(compiler::best_compilation(self)?),
508                DescriptorCtx::ShWsh => Descriptor::new_sh_wsh(compiler::best_compilation(self)?),
509                DescriptorCtx::Tr(unspendable_key) => self.compile_tr(unspendable_key),
510            },
511        }
512    }
513
514    /// Compile the descriptor into an optimized `Miniscript` representation
515    ///
516    /// # NOTE:
517    ///
518    /// It is **not recommended** to use policy as a stable identifier for a miniscript.
519    /// You should use the policy compiler once, and then use the miniscript output as a stable identifier.
520    /// See the compiler document in doc/compiler.md for more details.
521    #[cfg(feature = "compiler")]
522    pub fn compile<Ctx: ScriptContext>(&self) -> Result<Miniscript<Pk, Ctx>, CompilerError> {
523        self.is_valid()?;
524        match self.is_safe_nonmalleable() {
525            (false, _) => Err(CompilerError::TopLevelNonSafe),
526            (_, false) => Err(CompilerError::ImpossibleNonMalleableCompilation),
527            _ => compiler::best_compilation(self),
528        }
529    }
530}
531
532#[cfg(feature = "compiler")]
533impl<Pk: MiniscriptKey> PolicyArc<Pk> {
534    /// Given a [`Policy`], return a vector of policies whose disjunction is isomorphic to the initial one.
535    /// This function is supposed to incrementally expand i.e. represent the policy as disjunction over
536    /// sub-policies output by it. The probability calculations are similar as
537    /// [to_tapleaf_prob_vec][`Policy::to_tapleaf_prob_vec`]
538    #[cfg(feature = "compiler")]
539    fn enumerate_pol(&self, prob: f64) -> Vec<(f64, Arc<Self>)> {
540        match self {
541            PolicyArc::Or(subs) => {
542                let total_odds = subs.iter().fold(0, |acc, x| acc + x.0);
543                subs.iter()
544                    .map(|(odds, pol)| (prob * *odds as f64 / total_odds as f64, pol.clone()))
545                    .collect::<Vec<_>>()
546            }
547            PolicyArc::Threshold(k, subs) if *k == 1 => {
548                let total_odds = subs.len();
549                subs.iter()
550                    .map(|pol| (prob / total_odds as f64, pol.clone()))
551                    .collect::<Vec<_>>()
552            }
553            PolicyArc::Threshold(k, subs) if *k != subs.len() => {
554                generate_combination(subs, prob, *k)
555            }
556            pol => vec![(prob, Arc::new(pol.clone()))],
557        }
558    }
559
560    /// Generates a root-level disjunctive tree over the given policy tree.
561    ///
562    /// Uses a fixed-point algorithm to enumerate the disjunctions until exhaustive root-level
563    /// enumeration or limits exceed. For a given [`Policy`], we maintain an [ordered
564    /// set](`BTreeSet`) of `(prob, policy)` (ordered by probability) to maintain the list of
565    /// enumerated sub-policies whose disjunction is isomorphic to initial policy (*invariant*).
566    ///
567    /// [`Policy`]: crate::policy::concrete::Policy
568    #[cfg(feature = "compiler")]
569    fn enumerate_policy_tree(self, prob: f64) -> Vec<(f64, Arc<Self>)> {
570        let mut tapleaf_prob_vec = BTreeSet::<(Reverse<OrdF64>, Arc<Self>)>::new();
571        // Store probability corresponding to policy in the enumerated tree. This is required since
572        // owing to the current [policy element enumeration algorithm][`Policy::enumerate_pol`],
573        // two passes of the algorithm might result in same sub-policy showing up. Currently, we
574        // merge the nodes by adding up the corresponding probabilities for the same policy.
575        let mut pol_prob_map = HashMap::<Arc<Self>, OrdF64>::new();
576
577        let arc_self = Arc::new(self);
578        tapleaf_prob_vec.insert((Reverse(OrdF64(prob)), Arc::clone(&arc_self)));
579        pol_prob_map.insert(Arc::clone(&arc_self), OrdF64(prob));
580
581        // Since we know that policy enumeration *must* result in increase in total number of nodes,
582        // we can maintain the length of the ordered set to check if the
583        // [enumeration pass][`Policy::enumerate_pol`] results in further policy split or not.
584        let mut prev_len = 0usize;
585        // This is required since we merge some corresponding policy nodes, so we can explicitly
586        // store the variables
587        let mut enum_len = tapleaf_prob_vec.len();
588
589        let mut ret: Vec<(f64, Arc<Self>)> = vec![];
590
591        // Stopping condition: When NONE of the inputs can be further enumerated.
592        'outer: loop {
593            //--- FIND a plausible node ---
594            let mut prob: Reverse<OrdF64> = Reverse(OrdF64(0.0));
595            let mut curr_policy: Arc<Self> = Arc::new(PolicyArc::Unsatisfiable);
596            let mut curr_pol_replace_vec: Vec<(f64, Arc<Self>)> = vec![];
597            let mut no_more_enum = false;
598
599            // The nodes which can't be enumerated further are directly appended to ret and removed
600            // from the ordered set.
601            let mut to_del: Vec<(f64, Arc<Self>)> = vec![];
602            'inner: for (i, (p, pol)) in tapleaf_prob_vec.iter().enumerate() {
603                curr_pol_replace_vec = pol.enumerate_pol(p.0 .0);
604                enum_len += curr_pol_replace_vec.len() - 1; // A disjunctive node should have seperated this into more nodes
605                assert!(prev_len <= enum_len);
606
607                if prev_len < enum_len {
608                    // Plausible node found
609                    prob = *p;
610                    curr_policy = Arc::clone(pol);
611                    break 'inner;
612                } else if i == tapleaf_prob_vec.len() - 1 {
613                    // No enumerable node found i.e. STOP
614                    // Move all the elements to final return set
615                    no_more_enum = true;
616                } else {
617                    // Either node is enumerable, or we have
618                    // Mark all non-enumerable nodes to remove,
619                    // if not returning value in the current iteration.
620                    to_del.push((p.0 .0, Arc::clone(pol)));
621                }
622            }
623
624            // --- Sanity Checks ---
625            if enum_len > MAX_COMPILATION_LEAVES || no_more_enum {
626                for (p, pol) in tapleaf_prob_vec.into_iter() {
627                    ret.push((p.0 .0, pol));
628                }
629                break 'outer;
630            }
631
632            // If total number of nodes are in limits, we remove the current node and replace it
633            // with children nodes
634
635            // Remove current node
636            assert!(tapleaf_prob_vec.remove(&(prob, curr_policy.clone())));
637
638            // OPTIMIZATION - Move marked nodes into final vector
639            for (p, pol) in to_del {
640                assert!(tapleaf_prob_vec.remove(&(Reverse(OrdF64(p)), pol.clone())));
641                ret.push((p, pol.clone()));
642            }
643
644            // Append node if not previously exists, else update the respective probability
645            for (p, policy) in curr_pol_replace_vec {
646                match pol_prob_map.get(&policy) {
647                    Some(prev_prob) => {
648                        assert!(tapleaf_prob_vec.remove(&(Reverse(*prev_prob), policy.clone())));
649                        tapleaf_prob_vec.insert((Reverse(OrdF64(prev_prob.0 + p)), policy.clone()));
650                        pol_prob_map.insert(policy.clone(), OrdF64(prev_prob.0 + p));
651                    }
652                    None => {
653                        tapleaf_prob_vec.insert((Reverse(OrdF64(p)), policy.clone()));
654                        pol_prob_map.insert(policy.clone(), OrdF64(p));
655                    }
656                }
657            }
658            // --- Update --- total sub-policies count (considering no merging of nodes)
659            prev_len = enum_len;
660        }
661
662        ret
663    }
664}
665
666impl<Pk: MiniscriptKey> ForEachKey<Pk> for Policy<Pk> {
667    fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
668        self.real_for_each_key(&mut pred)
669    }
670}
671
672impl<Pk: MiniscriptKey> Policy<Pk> {
673    fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool {
674        match *self {
675            Policy::Unsatisfiable | Policy::Trivial => true,
676            Policy::Key(ref pk) => pred(pk),
677            Policy::Sha256(..)
678            | Policy::Hash256(..)
679            | Policy::Ripemd160(..)
680            | Policy::Hash160(..)
681            | Policy::After(..)
682            | Policy::Older(..) => true,
683            Policy::Threshold(_, ref subs) | Policy::And(ref subs) => {
684                subs.iter().all(|sub| sub.real_for_each_key(&mut *pred))
685            }
686            Policy::Or(ref subs) => subs
687                .iter()
688                .all(|(_, sub)| sub.real_for_each_key(&mut *pred)),
689        }
690    }
691
692    /// Convert a policy using one kind of public key to another
693    /// type of public key
694    ///
695    /// # Example
696    ///
697    /// ```
698    /// use miniscript::{bellscoin::PublicKey, policy::concrete::Policy, Translator, hash256};
699    /// use std::str::FromStr;
700    /// use miniscript::translate_hash_fail;
701    /// use std::collections::HashMap;
702    /// use miniscript::bellscoin::hashes::{sha256, hash160, ripemd160};
703    /// let alice_key = "0270cf3c71f65a3d93d285d9149fddeeb638f87a2d4d8cf16c525f71c417439777";
704    /// let bob_key = "02f43b15c50a436f5335dbea8a64dd3b4e63e34c3b50c42598acb5f4f336b5d2fb";
705    /// let placeholder_policy = Policy::<String>::from_str("and(pk(alice_key),pk(bob_key))").unwrap();
706    ///
707    /// // Information to translator abstract String type keys to concrete bellscoin::PublicKey.
708    /// // In practice, wallets would map from String key names to BIP32 keys
709    /// struct StrPkTranslator {
710    ///     pk_map: HashMap<String, bellscoin::PublicKey>
711    /// }
712    ///
713    /// // If we also wanted to provide mapping of other associated types(sha256, older etc),
714    /// // we would use the general Translator Trait.
715    /// impl Translator<String, bellscoin::PublicKey, ()> for StrPkTranslator {
716    ///     // Provides the translation public keys P -> Q
717    ///     fn pk(&mut self, pk: &String) -> Result<bellscoin::PublicKey, ()> {
718    ///         self.pk_map.get(pk).copied().ok_or(()) // Dummy Err
719    ///     }
720    ///
721    ///     // Fail for hash types
722    ///     translate_hash_fail!(String, bellscoin::PublicKey, ());
723    /// }
724    ///
725    /// let mut pk_map = HashMap::new();
726    /// pk_map.insert(String::from("alice_key"), bellscoin::PublicKey::from_str(alice_key).unwrap());
727    /// pk_map.insert(String::from("bob_key"), bellscoin::PublicKey::from_str(bob_key).unwrap());
728    /// let mut t = StrPkTranslator { pk_map: pk_map };
729    ///
730    /// let real_policy = placeholder_policy.translate_pk(&mut t).unwrap();
731    ///
732    /// let expected_policy = Policy::from_str(&format!("and(pk({}),pk({}))", alice_key, bob_key)).unwrap();
733    /// assert_eq!(real_policy, expected_policy);
734    /// ```
735    pub fn translate_pk<Q, E, T>(&self, t: &mut T) -> Result<Policy<Q>, E>
736    where
737        T: Translator<Pk, Q, E>,
738        Q: MiniscriptKey,
739    {
740        self._translate_pk(t)
741    }
742
743    fn _translate_pk<Q, E, T>(&self, t: &mut T) -> Result<Policy<Q>, E>
744    where
745        T: Translator<Pk, Q, E>,
746        Q: MiniscriptKey,
747    {
748        match *self {
749            Policy::Unsatisfiable => Ok(Policy::Unsatisfiable),
750            Policy::Trivial => Ok(Policy::Trivial),
751            Policy::Key(ref pk) => t.pk(pk).map(Policy::Key),
752            Policy::Sha256(ref h) => t.sha256(h).map(Policy::Sha256),
753            Policy::Hash256(ref h) => t.hash256(h).map(Policy::Hash256),
754            Policy::Ripemd160(ref h) => t.ripemd160(h).map(Policy::Ripemd160),
755            Policy::Hash160(ref h) => t.hash160(h).map(Policy::Hash160),
756            Policy::Older(n) => Ok(Policy::Older(n)),
757            Policy::After(n) => Ok(Policy::After(n)),
758            Policy::Threshold(k, ref subs) => {
759                let new_subs: Result<Vec<Policy<Q>>, _> =
760                    subs.iter().map(|sub| sub._translate_pk(t)).collect();
761                new_subs.map(|ok| Policy::Threshold(k, ok))
762            }
763            Policy::And(ref subs) => Ok(Policy::And(
764                subs.iter()
765                    .map(|sub| sub._translate_pk(t))
766                    .collect::<Result<Vec<Policy<Q>>, E>>()?,
767            )),
768            Policy::Or(ref subs) => Ok(Policy::Or(
769                subs.iter()
770                    .map(|(prob, sub)| Ok((*prob, sub._translate_pk(t)?)))
771                    .collect::<Result<Vec<(usize, Policy<Q>)>, E>>()?,
772            )),
773        }
774    }
775
776    /// Translate `Concrete::Key(key)` to `Concrete::Unsatisfiable` when extracting TapKey
777    pub fn translate_unsatisfiable_pk(self, key: &Pk) -> Policy<Pk> {
778        match self {
779            Policy::Key(ref k) if k.clone() == *key => Policy::Unsatisfiable,
780            Policy::And(subs) => Policy::And(
781                subs.into_iter()
782                    .map(|sub| sub.translate_unsatisfiable_pk(key))
783                    .collect::<Vec<_>>(),
784            ),
785            Policy::Or(subs) => Policy::Or(
786                subs.into_iter()
787                    .map(|(k, sub)| (k, sub.translate_unsatisfiable_pk(key)))
788                    .collect::<Vec<_>>(),
789            ),
790            Policy::Threshold(k, subs) => Policy::Threshold(
791                k,
792                subs.into_iter()
793                    .map(|sub| sub.translate_unsatisfiable_pk(key))
794                    .collect::<Vec<_>>(),
795            ),
796            x => x,
797        }
798    }
799
800    /// Get all keys in the policy
801    pub fn keys(&self) -> Vec<&Pk> {
802        match *self {
803            Policy::Key(ref pk) => vec![pk],
804            Policy::Threshold(_k, ref subs) => {
805                subs.iter().flat_map(|sub| sub.keys()).collect::<Vec<_>>()
806            }
807            Policy::And(ref subs) => subs.iter().flat_map(|sub| sub.keys()).collect::<Vec<_>>(),
808            Policy::Or(ref subs) => subs
809                .iter()
810                .flat_map(|(ref _k, ref sub)| sub.keys())
811                .collect::<Vec<_>>(),
812            // map all hashes and time
813            _ => vec![],
814        }
815    }
816
817    /// Get the number of [TapLeaf][`TapTree::Leaf`] considering exhaustive root-level [OR][`Policy::Or`]
818    /// and [Thresh][`Policy::Threshold`] disjunctions for the TapTree.
819    #[cfg(feature = "compiler")]
820    fn num_tap_leaves(&self) -> usize {
821        match self {
822            Policy::Or(subs) => subs.iter().map(|(_prob, pol)| pol.num_tap_leaves()).sum(),
823            Policy::Threshold(k, subs) if *k == 1 => {
824                subs.iter().map(|pol| pol.num_tap_leaves()).sum()
825            }
826            _ => 1,
827        }
828    }
829
830    /// Check on the number of TapLeaves
831    #[cfg(feature = "compiler")]
832    fn check_num_tapleaves(&self) -> Result<(), Error> {
833        if self.num_tap_leaves() > MAX_COMPILATION_LEAVES {
834            return Err(errstr("Too many Tapleaves"));
835        }
836        Ok(())
837    }
838
839    /// Check whether the policy contains duplicate public keys
840    pub fn check_duplicate_keys(&self) -> Result<(), PolicyError> {
841        let pks = self.keys();
842        let pks_len = pks.len();
843        let unique_pks_len = pks.into_iter().collect::<HashSet<_>>().len();
844
845        if pks_len > unique_pks_len {
846            Err(PolicyError::DuplicatePubKeys)
847        } else {
848            Ok(())
849        }
850    }
851
852    /// Checks whether the given concrete policy contains a combination of
853    /// timelocks and heightlocks.
854    /// Returns an error if there is at least one satisfaction that contains
855    /// a combination of hieghtlock and timelock.
856    pub fn check_timelocks(&self) -> Result<(), PolicyError> {
857        let timelocks = self.check_timelocks_helper();
858        if timelocks.contains_combination {
859            Err(PolicyError::HeightTimelockCombination)
860        } else {
861            Ok(())
862        }
863    }
864
865    // Checks whether the given concrete policy contains a combination of
866    // timelocks and heightlocks
867    fn check_timelocks_helper(&self) -> TimelockInfo {
868        // timelocks[csv_h, csv_t, cltv_h, cltv_t, combination]
869        match *self {
870            Policy::Unsatisfiable
871            | Policy::Trivial
872            | Policy::Key(_)
873            | Policy::Sha256(_)
874            | Policy::Hash256(_)
875            | Policy::Ripemd160(_)
876            | Policy::Hash160(_) => TimelockInfo::default(),
877            Policy::After(t) => TimelockInfo {
878                csv_with_height: false,
879                csv_with_time: false,
880                cltv_with_height: absolute::LockTime::from(t).is_block_height(),
881                cltv_with_time: absolute::LockTime::from(t).is_block_time(),
882                contains_combination: false,
883            },
884            Policy::Older(t) => TimelockInfo {
885                csv_with_height: t.is_height_locked(),
886                csv_with_time: t.is_time_locked(),
887                cltv_with_height: false,
888                cltv_with_time: false,
889                contains_combination: false,
890            },
891            Policy::Threshold(k, ref subs) => {
892                let iter = subs.iter().map(|sub| sub.check_timelocks_helper());
893                TimelockInfo::combine_threshold(k, iter)
894            }
895            Policy::And(ref subs) => {
896                let iter = subs.iter().map(|sub| sub.check_timelocks_helper());
897                TimelockInfo::combine_threshold(subs.len(), iter)
898            }
899            Policy::Or(ref subs) => {
900                let iter = subs.iter().map(|(_p, sub)| sub.check_timelocks_helper());
901                TimelockInfo::combine_threshold(1, iter)
902            }
903        }
904    }
905
906    /// This returns whether the given policy is valid or not. It maybe possible that the policy
907    /// contains Non-two argument `and`, `or` or a `0` arg thresh.
908    /// Validity condition also checks whether there is a possible satisfaction
909    /// combination of timelocks and heightlocks
910    pub fn is_valid(&self) -> Result<(), PolicyError> {
911        self.check_timelocks()?;
912        self.check_duplicate_keys()?;
913        match *self {
914            Policy::And(ref subs) => {
915                if subs.len() != 2 {
916                    Err(PolicyError::NonBinaryArgAnd)
917                } else {
918                    subs.iter()
919                        .map(|sub| sub.is_valid())
920                        .collect::<Result<Vec<()>, PolicyError>>()?;
921                    Ok(())
922                }
923            }
924            Policy::Or(ref subs) => {
925                if subs.len() != 2 {
926                    Err(PolicyError::NonBinaryArgOr)
927                } else {
928                    subs.iter()
929                        .map(|(_prob, sub)| sub.is_valid())
930                        .collect::<Result<Vec<()>, PolicyError>>()?;
931                    Ok(())
932                }
933            }
934            Policy::Threshold(k, ref subs) => {
935                if k == 0 || k > subs.len() {
936                    Err(PolicyError::IncorrectThresh)
937                } else {
938                    subs.iter()
939                        .map(|sub| sub.is_valid())
940                        .collect::<Result<Vec<()>, PolicyError>>()?;
941                    Ok(())
942                }
943            }
944            Policy::After(n) => {
945                if n == absolute::LockTime::ZERO.into() {
946                    Err(PolicyError::ZeroTime)
947                } else if n.to_u32() > 2u32.pow(31) {
948                    Err(PolicyError::TimeTooFar)
949                } else {
950                    Ok(())
951                }
952            }
953            Policy::Older(n) => {
954                if n == Sequence::ZERO {
955                    Err(PolicyError::ZeroTime)
956                } else if n.to_consensus_u32() > 2u32.pow(31) {
957                    Err(PolicyError::TimeTooFar)
958                } else {
959                    Ok(())
960                }
961            }
962            _ => Ok(()),
963        }
964    }
965    /// This returns whether any possible compilation of the policy could be
966    /// compiled as non-malleable and safe. Note that this returns a tuple
967    /// (safe, non-malleable) to avoid because the non-malleability depends on
968    /// safety and we would like to cache results.
969    ///
970    pub fn is_safe_nonmalleable(&self) -> (bool, bool) {
971        match *self {
972            Policy::Unsatisfiable | Policy::Trivial => (true, true),
973            Policy::Key(_) => (true, true),
974            Policy::Sha256(_)
975            | Policy::Hash256(_)
976            | Policy::Ripemd160(_)
977            | Policy::Hash160(_)
978            | Policy::After(_)
979            | Policy::Older(_) => (false, true),
980            Policy::Threshold(k, ref subs) => {
981                let (safe_count, non_mall_count) = subs
982                    .iter()
983                    .map(|sub| sub.is_safe_nonmalleable())
984                    .fold((0, 0), |(safe_count, non_mall_count), (safe, non_mall)| {
985                        (
986                            safe_count + safe as usize,
987                            non_mall_count + non_mall as usize,
988                        )
989                    });
990                (
991                    safe_count >= (subs.len() - k + 1),
992                    non_mall_count == subs.len() && safe_count >= (subs.len() - k),
993                )
994            }
995            Policy::And(ref subs) => {
996                let (atleast_one_safe, all_non_mall) = subs
997                    .iter()
998                    .map(|sub| sub.is_safe_nonmalleable())
999                    .fold((false, true), |acc, x| (acc.0 || x.0, acc.1 && x.1));
1000                (atleast_one_safe, all_non_mall)
1001            }
1002
1003            Policy::Or(ref subs) => {
1004                let (all_safe, atleast_one_safe, all_non_mall) = subs
1005                    .iter()
1006                    .map(|(_, sub)| sub.is_safe_nonmalleable())
1007                    .fold((true, false, true), |acc, x| {
1008                        (acc.0 && x.0, acc.1 || x.0, acc.2 && x.1)
1009                    });
1010                (all_safe, atleast_one_safe && all_non_mall)
1011            }
1012        }
1013    }
1014}
1015
1016impl<Pk: MiniscriptKey> fmt::Debug for Policy<Pk> {
1017    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1018        match *self {
1019            Policy::Unsatisfiable => f.write_str("UNSATISFIABLE()"),
1020            Policy::Trivial => f.write_str("TRIVIAL()"),
1021            Policy::Key(ref pk) => write!(f, "pk({:?})", pk),
1022            Policy::After(n) => write!(f, "after({})", n),
1023            Policy::Older(n) => write!(f, "older({})", n),
1024            Policy::Sha256(ref h) => write!(f, "sha256({})", h),
1025            Policy::Hash256(ref h) => write!(f, "hash256({})", h),
1026            Policy::Ripemd160(ref h) => write!(f, "ripemd160({})", h),
1027            Policy::Hash160(ref h) => write!(f, "hash160({})", h),
1028            Policy::And(ref subs) => {
1029                f.write_str("and(")?;
1030                if !subs.is_empty() {
1031                    write!(f, "{:?}", subs[0])?;
1032                    for sub in &subs[1..] {
1033                        write!(f, ",{:?}", sub)?;
1034                    }
1035                }
1036                f.write_str(")")
1037            }
1038            Policy::Or(ref subs) => {
1039                f.write_str("or(")?;
1040                if !subs.is_empty() {
1041                    write!(f, "{}@{:?}", subs[0].0, subs[0].1)?;
1042                    for sub in &subs[1..] {
1043                        write!(f, ",{}@{:?}", sub.0, sub.1)?;
1044                    }
1045                }
1046                f.write_str(")")
1047            }
1048            Policy::Threshold(k, ref subs) => {
1049                write!(f, "thresh({}", k)?;
1050                for sub in subs {
1051                    write!(f, ",{:?}", sub)?;
1052                }
1053                f.write_str(")")
1054            }
1055        }
1056    }
1057}
1058
1059impl<Pk: MiniscriptKey> fmt::Display for Policy<Pk> {
1060    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1061        match *self {
1062            Policy::Unsatisfiable => f.write_str("UNSATISFIABLE"),
1063            Policy::Trivial => f.write_str("TRIVIAL"),
1064            Policy::Key(ref pk) => write!(f, "pk({})", pk),
1065            Policy::After(n) => write!(f, "after({})", n),
1066            Policy::Older(n) => write!(f, "older({})", n),
1067            Policy::Sha256(ref h) => write!(f, "sha256({})", h),
1068            Policy::Hash256(ref h) => write!(f, "hash256({})", h),
1069            Policy::Ripemd160(ref h) => write!(f, "ripemd160({})", h),
1070            Policy::Hash160(ref h) => write!(f, "hash160({})", h),
1071            Policy::And(ref subs) => {
1072                f.write_str("and(")?;
1073                if !subs.is_empty() {
1074                    write!(f, "{}", subs[0])?;
1075                    for sub in &subs[1..] {
1076                        write!(f, ",{}", sub)?;
1077                    }
1078                }
1079                f.write_str(")")
1080            }
1081            Policy::Or(ref subs) => {
1082                f.write_str("or(")?;
1083                if !subs.is_empty() {
1084                    write!(f, "{}@{}", subs[0].0, subs[0].1)?;
1085                    for sub in &subs[1..] {
1086                        write!(f, ",{}@{}", sub.0, sub.1)?;
1087                    }
1088                }
1089                f.write_str(")")
1090            }
1091            Policy::Threshold(k, ref subs) => {
1092                write!(f, "thresh({}", k)?;
1093                for sub in subs {
1094                    write!(f, ",{}", sub)?;
1095                }
1096                f.write_str(")")
1097            }
1098        }
1099    }
1100}
1101
1102impl_from_str!(
1103    Policy<Pk>,
1104    type Err = Error;,
1105    fn from_str(s: &str) -> Result<Policy<Pk>, Error> {
1106        for ch in s.as_bytes() {
1107            if *ch < 20 || *ch > 127 {
1108                return Err(Error::Unprintable(*ch));
1109            }
1110        }
1111
1112        let tree = expression::Tree::from_str(s)?;
1113        let policy: Policy<Pk> = FromTree::from_tree(&tree)?;
1114        policy.check_timelocks()?;
1115        Ok(policy)
1116    }
1117);
1118
1119serde_string_impl_pk!(Policy, "a miniscript concrete policy");
1120
1121#[rustfmt::skip]
1122impl_block_str!(
1123    Policy<Pk>,
1124    /// Helper function for `from_tree` to parse subexpressions with
1125    /// names of the form x@y
1126    fn from_tree_prob(top: &expression::Tree, allow_prob: bool,)
1127        -> Result<(usize, Policy<Pk>), Error>
1128    {
1129        let frag_prob;
1130        let frag_name;
1131        let mut name_split = top.name.split('@');
1132        match (name_split.next(), name_split.next(), name_split.next()) {
1133            (None, _, _) => {
1134                frag_prob = 1;
1135                frag_name = "";
1136            }
1137            (Some(name), None, _) => {
1138                frag_prob = 1;
1139                frag_name = name;
1140            }
1141            (Some(prob), Some(name), None) => {
1142                if !allow_prob {
1143                    return Err(Error::AtOutsideOr(top.name.to_owned()));
1144                }
1145                frag_prob = expression::parse_num(prob)? as usize;
1146                frag_name = name;
1147            }
1148            (Some(_), Some(_), Some(_)) => {
1149                return Err(Error::MultiColon(top.name.to_owned()));
1150            }
1151        }
1152        match (frag_name, top.args.len() as u32) {
1153            ("UNSATISFIABLE", 0) => Ok(Policy::Unsatisfiable),
1154            ("TRIVIAL", 0) => Ok(Policy::Trivial),
1155            ("pk", 1) => expression::terminal(&top.args[0], |pk| Pk::from_str(pk).map(Policy::Key)),
1156            ("after", 1) => {
1157                let num = expression::terminal(&top.args[0], expression::parse_num)?;
1158                if num > 2u32.pow(31) {
1159                    return Err(Error::PolicyError(PolicyError::TimeTooFar));
1160                } else if num == 0 {
1161                    return Err(Error::PolicyError(PolicyError::ZeroTime));
1162                }
1163                Ok(Policy::after(num))
1164            }
1165            ("older", 1) => {
1166                let num = expression::terminal(&top.args[0], expression::parse_num)?;
1167                if num > 2u32.pow(31) {
1168                    return Err(Error::PolicyError(PolicyError::TimeTooFar));
1169                } else if num == 0 {
1170                    return Err(Error::PolicyError(PolicyError::ZeroTime));
1171                }
1172                Ok(Policy::older(num))
1173            }
1174            ("sha256", 1) => expression::terminal(&top.args[0], |x| {
1175                <Pk::Sha256 as core::str::FromStr>::from_str(x).map(Policy::Sha256)
1176            }),
1177            ("hash256", 1) => expression::terminal(&top.args[0], |x| {
1178                <Pk::Hash256 as core::str::FromStr>::from_str(x).map(Policy::Hash256)
1179            }),
1180            ("ripemd160", 1) => expression::terminal(&top.args[0], |x| {
1181                <Pk::Ripemd160 as core::str::FromStr>::from_str(x).map(Policy::Ripemd160)
1182            }),
1183            ("hash160", 1) => expression::terminal(&top.args[0], |x| {
1184                <Pk::Hash160 as core::str::FromStr>::from_str(x).map(Policy::Hash160)
1185            }),
1186            ("and", _) => {
1187                if top.args.len() != 2 {
1188                    return Err(Error::PolicyError(PolicyError::NonBinaryArgAnd));
1189                }
1190                let mut subs = Vec::with_capacity(top.args.len());
1191                for arg in &top.args {
1192                    subs.push(Policy::from_tree(arg)?);
1193                }
1194                Ok(Policy::And(subs))
1195            }
1196            ("or", _) => {
1197                if top.args.len() != 2 {
1198                    return Err(Error::PolicyError(PolicyError::NonBinaryArgOr));
1199                }
1200                let mut subs = Vec::with_capacity(top.args.len());
1201                for arg in &top.args {
1202                    subs.push(Policy::from_tree_prob(arg, true)?);
1203                }
1204                Ok(Policy::Or(subs))
1205            }
1206            ("thresh", nsubs) => {
1207                if top.args.is_empty() || !top.args[0].args.is_empty() {
1208                    return Err(Error::PolicyError(PolicyError::IncorrectThresh));
1209                }
1210
1211                let thresh = expression::parse_num(top.args[0].name)?;
1212                if thresh >= nsubs || thresh == 0 {
1213                    return Err(Error::PolicyError(PolicyError::IncorrectThresh));
1214                }
1215
1216                let mut subs = Vec::with_capacity(top.args.len() - 1);
1217                for arg in &top.args[1..] {
1218                    subs.push(Policy::from_tree(arg)?);
1219                }
1220                Ok(Policy::Threshold(thresh as usize, subs))
1221            }
1222            _ => Err(errstr(top.name)),
1223        }
1224        .map(|res| (frag_prob, res))
1225    }
1226);
1227
1228impl_from_tree!(
1229    Policy<Pk>,
1230    fn from_tree(top: &expression::Tree) -> Result<Policy<Pk>, Error> {
1231        Policy::from_tree_prob(top, false).map(|(_, result)| result)
1232    }
1233);
1234
1235/// Create a Huffman Tree from compiled [Miniscript] nodes
1236#[cfg(feature = "compiler")]
1237fn with_huffman_tree<Pk: MiniscriptKey>(
1238    ms: Vec<(OrdF64, Miniscript<Pk, Tap>)>,
1239) -> Result<TapTree<Pk>, Error> {
1240    let mut node_weights = BinaryHeap::<(Reverse<OrdF64>, TapTree<Pk>)>::new();
1241    for (prob, script) in ms {
1242        node_weights.push((Reverse(prob), TapTree::Leaf(Arc::new(script))));
1243    }
1244    if node_weights.is_empty() {
1245        return Err(errstr("Empty Miniscript compilation"));
1246    }
1247    while node_weights.len() > 1 {
1248        let (p1, s1) = node_weights.pop().expect("len must atleast be two");
1249        let (p2, s2) = node_weights.pop().expect("len must atleast be two");
1250
1251        let p = (p1.0).0 + (p2.0).0;
1252        node_weights.push((
1253            Reverse(OrdF64(p)),
1254            TapTree::Tree(Arc::from(s1), Arc::from(s2)),
1255        ));
1256    }
1257
1258    debug_assert!(node_weights.len() == 1);
1259    let node = node_weights
1260        .pop()
1261        .expect("huffman tree algorithm is broken")
1262        .1;
1263    Ok(node)
1264}
1265
1266/// Enumerate a [Thresh][`Policy::Threshold`](k, ..n..) into `n` different thresh.
1267///
1268/// ## Strategy
1269///
1270/// `thresh(k, x_1...x_n) := thresh(1, thresh(k, x_2...x_n), thresh(k, x_1x_3...x_n), ...., thresh(k, x_1...x_{n-1}))`
1271/// by the simple argument that choosing `k` conditions from `n` available conditions might not contain
1272/// any one of the conditions exclusively.
1273#[cfg(feature = "compiler")]
1274fn generate_combination<Pk: MiniscriptKey>(
1275    policy_vec: &Vec<Arc<PolicyArc<Pk>>>,
1276    prob: f64,
1277    k: usize,
1278) -> Vec<(f64, Arc<PolicyArc<Pk>>)> {
1279    debug_assert!(k <= policy_vec.len());
1280
1281    let mut ret: Vec<(f64, Arc<PolicyArc<Pk>>)> = vec![];
1282    for i in 0..policy_vec.len() {
1283        let policies: Vec<Arc<PolicyArc<Pk>>> = policy_vec
1284            .iter()
1285            .enumerate()
1286            .filter_map(|(j, sub)| if j != i { Some(Arc::clone(sub)) } else { None })
1287            .collect();
1288        ret.push((
1289            prob / policy_vec.len() as f64,
1290            Arc::new(PolicyArc::Threshold(k, policies)),
1291        ));
1292    }
1293    ret
1294}
1295
1296#[cfg(all(test, feature = "compiler"))]
1297mod compiler_tests {
1298    use core::str::FromStr;
1299
1300    use sync::Arc;
1301
1302    use super::Concrete;
1303    use crate::policy::concrete::{generate_combination, PolicyArc};
1304    use crate::prelude::*;
1305
1306    #[test]
1307    fn test_gen_comb() {
1308        let policies: Vec<Concrete<String>> = vec!["pk(A)", "pk(B)", "pk(C)", "pk(D)"]
1309            .into_iter()
1310            .map(|st| policy_str!("{}", st))
1311            .collect();
1312        let policy_vec = policies
1313            .into_iter()
1314            .map(|pol| Arc::new(PolicyArc::from(pol)))
1315            .collect::<Vec<_>>();
1316
1317        let combinations = generate_combination(&policy_vec, 1.0, 2);
1318
1319        let comb_a: Vec<Arc<PolicyArc<String>>> = vec![
1320            policy_str!("pk(B)"),
1321            policy_str!("pk(C)"),
1322            policy_str!("pk(D)"),
1323        ]
1324        .into_iter()
1325        .map(|pol| Arc::new(PolicyArc::from(pol)))
1326        .collect();
1327        let comb_b: Vec<Arc<PolicyArc<String>>> = vec![
1328            policy_str!("pk(A)"),
1329            policy_str!("pk(C)"),
1330            policy_str!("pk(D)"),
1331        ]
1332        .into_iter()
1333        .map(|pol| Arc::new(PolicyArc::from(pol)))
1334        .collect();
1335        let comb_c: Vec<Arc<PolicyArc<String>>> = vec![
1336            policy_str!("pk(A)"),
1337            policy_str!("pk(B)"),
1338            policy_str!("pk(D)"),
1339        ]
1340        .into_iter()
1341        .map(|pol| Arc::new(PolicyArc::from(pol)))
1342        .collect();
1343        let comb_d: Vec<Arc<PolicyArc<String>>> = vec![
1344            policy_str!("pk(A)"),
1345            policy_str!("pk(B)"),
1346            policy_str!("pk(C)"),
1347        ]
1348        .into_iter()
1349        .map(|pol| Arc::new(PolicyArc::from(pol)))
1350        .collect();
1351        let expected_comb = vec![comb_a, comb_b, comb_c, comb_d]
1352            .into_iter()
1353            .map(|sub_pol| (0.25, Arc::new(PolicyArc::Threshold(2, sub_pol))))
1354            .collect::<Vec<_>>();
1355        assert_eq!(combinations, expected_comb);
1356    }
1357}
1358
1359#[cfg(test)]
1360mod tests {
1361    use std::str::FromStr;
1362
1363    use super::*;
1364
1365    #[test]
1366    fn for_each_key() {
1367        let liquid_pol = Policy::<String>::from_str(
1368            "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();
1369        let mut count = 0;
1370        assert!(liquid_pol.for_each_key(|_| {
1371            count += 1;
1372            true
1373        }));
1374        assert_eq!(count, 17);
1375    }
1376}