@@ -140,6 +140,9 @@ pub struct ExtData {
140
140
/// This does **not** include initial witness elements. This element only captures
141
141
/// the additional elements that are pushed during execution.
142
142
pub exec_stack_elem_count_dissat : Option < usize > ,
143
+ /// The miniscript tree depth/height of this node.
144
+ /// Used for checking the max depth of the miniscript tree to prevent stack overflow.
145
+ pub tree_height : usize ,
143
146
}
144
147
145
148
impl ExtData {
@@ -155,6 +158,7 @@ impl ExtData {
155
158
timelock_info : TimelockInfo :: new ( ) ,
156
159
exec_stack_elem_count_sat : None ,
157
160
exec_stack_elem_count_dissat : Some ( 1 ) ,
161
+ tree_height : 0 ,
158
162
} ;
159
163
160
164
/// Extra data for the `1` combinator
@@ -169,6 +173,7 @@ impl ExtData {
169
173
timelock_info : TimelockInfo :: new ( ) ,
170
174
exec_stack_elem_count_sat : Some ( 1 ) ,
171
175
exec_stack_elem_count_dissat : None ,
176
+ tree_height : 0 ,
172
177
} ;
173
178
}
174
179
@@ -204,6 +209,7 @@ impl ExtData {
204
209
timelock_info : TimelockInfo :: default ( ) ,
205
210
exec_stack_elem_count_sat : Some ( 1 ) , // pushes the pk
206
211
exec_stack_elem_count_dissat : Some ( 1 ) ,
212
+ tree_height : 0 ,
207
213
}
208
214
}
209
215
@@ -226,6 +232,7 @@ impl ExtData {
226
232
timelock_info : TimelockInfo :: default ( ) ,
227
233
exec_stack_elem_count_sat : Some ( 2 ) , // dup and hash push
228
234
exec_stack_elem_count_dissat : Some ( 2 ) ,
235
+ tree_height : 0 ,
229
236
}
230
237
}
231
238
@@ -250,6 +257,7 @@ impl ExtData {
250
257
timelock_info : TimelockInfo :: new ( ) ,
251
258
exec_stack_elem_count_sat : Some ( n) , // n pks
252
259
exec_stack_elem_count_dissat : Some ( n) ,
260
+ tree_height : 0 ,
253
261
}
254
262
}
255
263
@@ -273,6 +281,7 @@ impl ExtData {
273
281
timelock_info : TimelockInfo :: new ( ) ,
274
282
exec_stack_elem_count_sat : Some ( 2 ) , // the two nums before num equal verify
275
283
exec_stack_elem_count_dissat : Some ( 2 ) ,
284
+ tree_height : 0 ,
276
285
}
277
286
}
278
287
@@ -289,6 +298,7 @@ impl ExtData {
289
298
timelock_info : TimelockInfo :: new ( ) ,
290
299
exec_stack_elem_count_sat : Some ( 2 ) , // either size <32> or <hash256> <32 byte>
291
300
exec_stack_elem_count_dissat : Some ( 2 ) ,
301
+ tree_height : 0 ,
292
302
}
293
303
}
294
304
@@ -305,6 +315,7 @@ impl ExtData {
305
315
timelock_info : TimelockInfo :: new ( ) ,
306
316
exec_stack_elem_count_sat : Some ( 2 ) , // either size <32> or <hash256> <32 byte>
307
317
exec_stack_elem_count_dissat : Some ( 2 ) ,
318
+ tree_height : 0 ,
308
319
}
309
320
}
310
321
@@ -321,6 +332,7 @@ impl ExtData {
321
332
timelock_info : TimelockInfo :: new ( ) ,
322
333
exec_stack_elem_count_sat : Some ( 2 ) , // either size <32> or <hash256> <20 byte>
323
334
exec_stack_elem_count_dissat : Some ( 2 ) ,
335
+ tree_height : 0 ,
324
336
}
325
337
}
326
338
@@ -337,6 +349,7 @@ impl ExtData {
337
349
timelock_info : TimelockInfo :: new ( ) ,
338
350
exec_stack_elem_count_sat : Some ( 2 ) , // either size <32> or <hash256> <20 byte>
339
351
exec_stack_elem_count_dissat : Some ( 2 ) ,
352
+ tree_height : 0 ,
340
353
}
341
354
}
342
355
@@ -359,6 +372,7 @@ impl ExtData {
359
372
} ,
360
373
exec_stack_elem_count_sat : Some ( 1 ) , // <t>
361
374
exec_stack_elem_count_dissat : None ,
375
+ tree_height : 0 ,
362
376
}
363
377
}
364
378
@@ -381,6 +395,7 @@ impl ExtData {
381
395
} ,
382
396
exec_stack_elem_count_sat : Some ( 1 ) , // <t>
383
397
exec_stack_elem_count_dissat : None ,
398
+ tree_height : 0 ,
384
399
}
385
400
}
386
401
@@ -397,6 +412,7 @@ impl ExtData {
397
412
timelock_info : self . timelock_info ,
398
413
exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
399
414
exec_stack_elem_count_dissat : self . exec_stack_elem_count_dissat ,
415
+ tree_height : self . tree_height + 1 ,
400
416
}
401
417
}
402
418
@@ -413,6 +429,7 @@ impl ExtData {
413
429
timelock_info : self . timelock_info ,
414
430
exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
415
431
exec_stack_elem_count_dissat : self . exec_stack_elem_count_dissat ,
432
+ tree_height : self . tree_height + 1 ,
416
433
}
417
434
}
418
435
@@ -429,6 +446,7 @@ impl ExtData {
429
446
timelock_info : self . timelock_info ,
430
447
exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
431
448
exec_stack_elem_count_dissat : self . exec_stack_elem_count_dissat ,
449
+ tree_height : self . tree_height + 1 ,
432
450
}
433
451
}
434
452
@@ -448,6 +466,7 @@ impl ExtData {
448
466
// Even all V types push something onto the stack and then remove them
449
467
exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
450
468
exec_stack_elem_count_dissat : Some ( 1 ) ,
469
+ tree_height : self . tree_height + 1 ,
451
470
}
452
471
}
453
472
@@ -465,6 +484,7 @@ impl ExtData {
465
484
timelock_info : self . timelock_info ,
466
485
exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
467
486
exec_stack_elem_count_dissat : None ,
487
+ tree_height : self . tree_height + 1 ,
468
488
}
469
489
}
470
490
@@ -481,6 +501,7 @@ impl ExtData {
481
501
timelock_info : self . timelock_info ,
482
502
exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
483
503
exec_stack_elem_count_dissat : Some ( 1 ) ,
504
+ tree_height : self . tree_height + 1 ,
484
505
}
485
506
}
486
507
@@ -498,6 +519,7 @@ impl ExtData {
498
519
// Technically max(1, self.exec_stack_elem_count_sat), same rationale as cast_dupif
499
520
exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
500
521
exec_stack_elem_count_dissat : self . exec_stack_elem_count_dissat ,
522
+ tree_height : self . tree_height + 1 ,
501
523
}
502
524
}
503
525
@@ -545,6 +567,7 @@ impl ExtData {
545
567
l. exec_stack_elem_count_dissat ,
546
568
r. exec_stack_elem_count_dissat . map ( |x| x + 1 ) ,
547
569
) ,
570
+ tree_height : 1 + cmp:: max ( l. tree_height , r. tree_height ) ,
548
571
}
549
572
}
550
573
@@ -569,6 +592,7 @@ impl ExtData {
569
592
r. exec_stack_elem_count_sat ,
570
593
) ,
571
594
exec_stack_elem_count_dissat : None ,
595
+ tree_height : 1 + cmp:: max ( l. tree_height , r. tree_height ) ,
572
596
}
573
597
}
574
598
@@ -609,6 +633,7 @@ impl ExtData {
609
633
l. exec_stack_elem_count_dissat ,
610
634
r. exec_stack_elem_count_dissat . map ( |x| x + 1 ) ,
611
635
) ,
636
+ tree_height : 1 + cmp:: max ( l. tree_height , r. tree_height ) ,
612
637
}
613
638
}
614
639
@@ -647,6 +672,7 @@ impl ExtData {
647
672
l. exec_stack_elem_count_dissat ,
648
673
r. exec_stack_elem_count_dissat . map ( |x| x + 1 ) ,
649
674
) ,
675
+ tree_height : 1 + cmp:: max ( l. tree_height , r. tree_height ) ,
650
676
}
651
677
}
652
678
@@ -678,6 +704,7 @@ impl ExtData {
678
704
opt_max ( r. exec_stack_elem_count_sat , l. exec_stack_elem_count_dissat ) ,
679
705
) ,
680
706
exec_stack_elem_count_dissat : None ,
707
+ tree_height : 1 + cmp:: max ( l. tree_height , r. tree_height ) ,
681
708
}
682
709
}
683
710
@@ -725,6 +752,7 @@ impl ExtData {
725
752
l. exec_stack_elem_count_dissat ,
726
753
r. exec_stack_elem_count_dissat ,
727
754
) ,
755
+ tree_height : 1 + cmp:: max ( l. tree_height , r. tree_height ) ,
728
756
}
729
757
}
730
758
@@ -768,6 +796,7 @@ impl ExtData {
768
796
a. exec_stack_elem_count_dissat ,
769
797
c. exec_stack_elem_count_dissat ,
770
798
) ,
799
+ tree_height : 1 + cmp:: max ( a. tree_height , cmp:: max ( b. tree_height , c. tree_height ) ) ,
771
800
}
772
801
}
773
802
@@ -788,6 +817,7 @@ impl ExtData {
788
817
// the max element count is same as max sat element count when satisfying one element + 1
789
818
let mut exec_stack_elem_count_sat_vec = Vec :: with_capacity ( n) ;
790
819
let mut exec_stack_elem_count_dissat = Some ( 0 ) ;
820
+ let mut max_child_height = 0 ;
791
821
792
822
for i in 0 ..n {
793
823
let sub = sub_ck ( i) ;
@@ -817,6 +847,7 @@ impl ExtData {
817
847
. push ( ( sub. exec_stack_elem_count_sat , sub. exec_stack_elem_count_dissat ) ) ;
818
848
exec_stack_elem_count_dissat =
819
849
opt_max ( exec_stack_elem_count_dissat, sub. exec_stack_elem_count_dissat ) ;
850
+ max_child_height = cmp:: max ( max_child_height, sub. tree_height ) ;
820
851
}
821
852
822
853
stack_elem_count_sat_vec. sort_by ( sat_minus_option_dissat) ;
@@ -887,6 +918,7 @@ impl ExtData {
887
918
timelock_info : TimelockInfo :: combine_threshold ( k, timelocks) ,
888
919
exec_stack_elem_count_sat,
889
920
exec_stack_elem_count_dissat,
921
+ tree_height : max_child_height + 1 ,
890
922
}
891
923
}
892
924
0 commit comments