miniscript_debug/policy/
concrete.rs

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