@@ -24,6 +24,7 @@ use bitcoin::hashes::{hash160, ripemd160};
2424#[ cfg( feature = "compiler" ) ]
2525use {
2626 crate :: descriptor:: TapTree ,
27+ crate :: miniscript:: limits:: MAX_COMPILATION_LEAVES ,
2728 crate :: miniscript:: ScriptContext ,
2829 crate :: policy:: compiler:: CompilerError ,
2930 crate :: policy:: compiler:: OrdF64 ,
@@ -278,6 +279,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
278279 ) ) ,
279280 _ => {
280281 let ( internal_key, policy) = self . clone ( ) . extract_key ( unspendable_key) ?;
282+ policy. check_num_tapleaves ( ) ?;
281283 let tree = Descriptor :: new_tr (
282284 internal_key,
283285 match policy {
@@ -501,6 +503,28 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
501503 }
502504 }
503505
506+ /// Get the number of [TapLeaf][`TapTree::Leaf`] considering exhaustive root-level [OR][`Policy::Or`]
507+ /// and [Thresh][`Policy::Threshold`] disjunctions for the TapTree.
508+ #[ cfg( feature = "compiler" ) ]
509+ fn num_tap_leaves ( & self ) -> usize {
510+ match self {
511+ Policy :: Or ( subs) => subs. iter ( ) . map ( |( _prob, pol) | pol. num_tap_leaves ( ) ) . sum ( ) ,
512+ Policy :: Threshold ( k, subs) if * k == 1 => {
513+ subs. iter ( ) . map ( |pol| pol. num_tap_leaves ( ) ) . sum ( )
514+ }
515+ _ => 1 ,
516+ }
517+ }
518+
519+ /// Check on the number of TapLeaves
520+ #[ cfg( feature = "compiler" ) ]
521+ fn check_num_tapleaves ( & self ) -> Result < ( ) , Error > {
522+ if self . num_tap_leaves ( ) > MAX_COMPILATION_LEAVES {
523+ return Err ( errstr ( "Too many Tapleaves" ) ) ;
524+ }
525+ Ok ( ( ) )
526+ }
527+
504528 /// Check whether the policy contains duplicate public keys
505529 pub fn check_duplicate_keys ( & self ) -> Result < ( ) , PolicyError > {
506530 let pks = self . keys ( ) ;
0 commit comments