@@ -278,6 +278,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
278278 ) ) ,
279279 _ => {
280280 let ( internal_key, policy) = self . clone ( ) . extract_key ( unspendable_key) ?;
281+ policy. check_tapleaf ( ) ?;
281282 let tree = Descriptor :: new_tr (
282283 internal_key,
283284 match policy {
@@ -501,6 +502,26 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
501502 }
502503 }
503504
505+ /// Get the number of [TapLeaf][`TapTree::Leaf`] considering exhaustive root-level [OR][`Policy::Or`]
506+ /// and [Thresh][`Policy::Threshold`] disjunctions for the TapTree.
507+ #[ cfg( feature = "compiler" ) ]
508+ fn num_tap_leaves ( & self ) -> usize {
509+ match self {
510+ Policy :: Or ( subs) => subs. iter ( ) . map ( |( _prob, pol) | pol. num_tap_leaves ( ) ) . sum ( ) ,
511+ Policy :: Threshold ( k, subs) if * k == 1 => combination ( subs. len ( ) , * k) ,
512+ _ => 1 ,
513+ }
514+ }
515+
516+ /// Check on the number of TapLeaves
517+ #[ cfg( feature = "compiler" ) ]
518+ fn check_tapleaf ( & self ) -> Result < ( ) , Error > {
519+ if self . num_tap_leaves ( ) > 100_000 {
520+ return Err ( errstr ( "Too many Tapleaves" ) ) ;
521+ }
522+ Ok ( ( ) )
523+ }
524+
504525 /// Check whether the policy contains duplicate public keys
505526 pub fn check_duplicate_keys ( & self ) -> Result < ( ) , PolicyError > {
506527 let pks = self . keys ( ) ;
@@ -918,5 +939,12 @@ fn with_huffman_tree<Pk: MiniscriptKey>(
918939 . pop ( )
919940 . expect ( "huffman tree algorithm is broken" )
920941 . 1 ;
921- Ok ( node)
942+
943+ #[ cfg( feature = "compiler" ) ]
944+ fn combination ( n : usize , k : usize ) -> usize {
945+ if k == 0 {
946+ 1
947+ } else {
948+ n * combination ( n - 1 , k - 1 ) / k
949+ }
922950}
0 commit comments