@@ -278,6 +278,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
278
278
) ) ,
279
279
_ => {
280
280
let ( internal_key, policy) = self . clone ( ) . extract_key ( unspendable_key) ?;
281
+ policy. check_tapleaf ( ) ?;
281
282
let tree = Descriptor :: new_tr (
282
283
internal_key,
283
284
match policy {
@@ -501,6 +502,26 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
501
502
}
502
503
}
503
504
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
+
504
525
/// Check whether the policy contains duplicate public keys
505
526
pub fn check_duplicate_keys ( & self ) -> Result < ( ) , PolicyError > {
506
527
let pks = self . keys ( ) ;
@@ -918,5 +939,12 @@ fn with_huffman_tree<Pk: MiniscriptKey>(
918
939
. pop ( )
919
940
. expect ( "huffman tree algorithm is broken" )
920
941
. 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
+ }
922
950
}
0 commit comments