Skip to main content

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