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