@@ -40,6 +40,10 @@ use crate::miniscript::types::extra_props::TimelockInfo;
4040use crate :: prelude:: * ;
4141use crate :: { errstr, Error , ForEachKey , MiniscriptKey , Translator } ;
4242
43+ /// Maximum TapLeafs allowed in a compiled TapTree
44+ #[ cfg( feature = "compiler" ) ]
45+ const MAX_COMPILATION_LEAVES : usize = 1024 ;
46+
4347/// Concrete policy which corresponds directly to a Miniscript structure,
4448/// and whose disjunctions are annotated with satisfaction probabilities
4549/// to assist the compiler
@@ -276,6 +280,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
276280 ) ) ,
277281 _ => {
278282 let ( internal_key, policy) = self . clone ( ) . extract_key ( unspendable_key) ?;
283+ policy. check_num_tapleaves ( ) ?;
279284 let tree = Descriptor :: new_tr (
280285 internal_key,
281286 match policy {
@@ -507,6 +512,28 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
507512 }
508513 }
509514
515+ /// Get the number of [TapLeaf][`TapTree::Leaf`] considering exhaustive root-level [OR][`Policy::Or`]
516+ /// and [Thresh][`Policy::Threshold`] disjunctions for the TapTree.
517+ #[ cfg( feature = "compiler" ) ]
518+ fn num_tap_leaves ( & self ) -> usize {
519+ match self {
520+ Policy :: Or ( subs) => subs. iter ( ) . map ( |( _prob, pol) | pol. num_tap_leaves ( ) ) . sum ( ) ,
521+ Policy :: Threshold ( k, subs) if * k == 1 => {
522+ subs. iter ( ) . map ( |pol| pol. num_tap_leaves ( ) ) . sum ( )
523+ }
524+ _ => 1 ,
525+ }
526+ }
527+
528+ /// Check on the number of TapLeaves
529+ #[ cfg( feature = "compiler" ) ]
530+ fn check_num_tapleaves ( & self ) -> Result < ( ) , Error > {
531+ if self . num_tap_leaves ( ) > MAX_COMPILATION_LEAVES {
532+ return Err ( errstr ( "Too many Tapleaves" ) ) ;
533+ }
534+ Ok ( ( ) )
535+ }
536+
510537 /// Check whether the policy contains duplicate public keys
511538 pub fn check_duplicate_keys ( & self ) -> Result < ( ) , PolicyError > {
512539 let pks = self . keys ( ) ;
0 commit comments