@@ -119,6 +119,14 @@ pub struct ExtData {
119
119
pub max_dissat_size : Option < ( usize , usize ) > ,
120
120
/// The timelock info about heightlocks and timelocks
121
121
pub timelock_info : TimeLockInfo ,
122
+ /// Maximum stack + alt stack size during satisfaction execution
123
+ /// This does **not** include initial witness elements. This element only captures
124
+ /// the additional elements that are pushed during execution.
125
+ pub exec_stack_elem_count_sat : Option < usize > ,
126
+ /// Maximum stack + alt stack size during dissat execution
127
+ /// This does **not** include initial witness elements. This element only captures
128
+ /// the additional elements that are pushed during execution.
129
+ pub exec_stack_elem_count_dissat : Option < usize > ,
122
130
}
123
131
124
132
impl Property for ExtData {
@@ -138,6 +146,8 @@ impl Property for ExtData {
138
146
max_sat_size : Some ( ( 0 , 0 ) ) ,
139
147
max_dissat_size : None ,
140
148
timelock_info : TimeLockInfo :: default ( ) ,
149
+ exec_stack_elem_count_sat : Some ( 1 ) ,
150
+ exec_stack_elem_count_dissat : None ,
141
151
}
142
152
}
143
153
@@ -153,6 +163,8 @@ impl Property for ExtData {
153
163
max_sat_size : None ,
154
164
max_dissat_size : Some ( ( 0 , 0 ) ) ,
155
165
timelock_info : TimeLockInfo :: default ( ) ,
166
+ exec_stack_elem_count_sat : None ,
167
+ exec_stack_elem_count_dissat : Some ( 1 ) ,
156
168
}
157
169
}
158
170
@@ -168,6 +180,8 @@ impl Property for ExtData {
168
180
max_sat_size : Some ( ( 73 , 73 ) ) ,
169
181
max_dissat_size : Some ( ( 1 , 1 ) ) ,
170
182
timelock_info : TimeLockInfo :: default ( ) ,
183
+ exec_stack_elem_count_sat : Some ( 1 ) , // pushes the pk
184
+ exec_stack_elem_count_dissat : Some ( 1 ) ,
171
185
}
172
186
}
173
187
@@ -183,6 +197,8 @@ impl Property for ExtData {
183
197
max_sat_size : Some ( ( 34 + 73 , 34 + 73 ) ) ,
184
198
max_dissat_size : Some ( ( 35 , 35 ) ) ,
185
199
timelock_info : TimeLockInfo :: default ( ) ,
200
+ exec_stack_elem_count_sat : Some ( 2 ) , // dup and hash push
201
+ exec_stack_elem_count_dissat : Some ( 2 ) ,
186
202
}
187
203
}
188
204
@@ -204,6 +220,8 @@ impl Property for ExtData {
204
220
max_sat_size : Some ( ( 1 + 73 * k, 1 + 73 * k) ) ,
205
221
max_dissat_size : Some ( ( 1 + k, 1 + k) ) ,
206
222
timelock_info : TimeLockInfo :: default ( ) ,
223
+ exec_stack_elem_count_sat : Some ( n) , // n pks
224
+ exec_stack_elem_count_dissat : Some ( n) ,
207
225
}
208
226
}
209
227
@@ -224,6 +242,8 @@ impl Property for ExtData {
224
242
max_sat_size : Some ( ( 33 , 33 ) ) ,
225
243
max_dissat_size : Some ( ( 33 , 33 ) ) ,
226
244
timelock_info : TimeLockInfo :: default ( ) ,
245
+ exec_stack_elem_count_sat : Some ( 2 ) , // either size <32> or <hash256> <32 byte>
246
+ exec_stack_elem_count_dissat : Some ( 2 ) ,
227
247
}
228
248
}
229
249
@@ -239,6 +259,8 @@ impl Property for ExtData {
239
259
max_sat_size : Some ( ( 33 , 33 ) ) ,
240
260
max_dissat_size : Some ( ( 33 , 33 ) ) ,
241
261
timelock_info : TimeLockInfo :: default ( ) ,
262
+ exec_stack_elem_count_sat : Some ( 2 ) , // either size <32> or <hash256> <32 byte>
263
+ exec_stack_elem_count_dissat : Some ( 2 ) ,
242
264
}
243
265
}
244
266
@@ -254,6 +276,8 @@ impl Property for ExtData {
254
276
max_sat_size : Some ( ( 33 , 33 ) ) ,
255
277
max_dissat_size : Some ( ( 33 , 33 ) ) ,
256
278
timelock_info : TimeLockInfo :: default ( ) ,
279
+ exec_stack_elem_count_sat : Some ( 2 ) , // either size <32> or <hash256> <20 byte>
280
+ exec_stack_elem_count_dissat : Some ( 2 ) ,
257
281
}
258
282
}
259
283
@@ -269,6 +293,8 @@ impl Property for ExtData {
269
293
max_sat_size : Some ( ( 33 , 33 ) ) ,
270
294
max_dissat_size : Some ( ( 33 , 33 ) ) ,
271
295
timelock_info : TimeLockInfo :: default ( ) ,
296
+ exec_stack_elem_count_sat : Some ( 2 ) , // either size <32> or <hash256> <20 byte>
297
+ exec_stack_elem_count_dissat : Some ( 2 ) ,
272
298
}
273
299
}
274
300
@@ -294,6 +320,8 @@ impl Property for ExtData {
294
320
cltv_with_time : t >= HEIGHT_TIME_THRESHOLD ,
295
321
contains_combination : false ,
296
322
} ,
323
+ exec_stack_elem_count_sat : Some ( 1 ) , // <t>
324
+ exec_stack_elem_count_dissat : None ,
297
325
}
298
326
}
299
327
@@ -315,6 +343,8 @@ impl Property for ExtData {
315
343
cltv_with_time : false ,
316
344
contains_combination : false ,
317
345
} ,
346
+ exec_stack_elem_count_sat : Some ( 1 ) , // <t>
347
+ exec_stack_elem_count_dissat : None ,
318
348
}
319
349
}
320
350
@@ -330,6 +360,8 @@ impl Property for ExtData {
330
360
max_sat_size : self . max_sat_size ,
331
361
max_dissat_size : self . max_dissat_size ,
332
362
timelock_info : self . timelock_info ,
363
+ exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
364
+ exec_stack_elem_count_dissat : self . exec_stack_elem_count_dissat ,
333
365
} )
334
366
}
335
367
@@ -345,6 +377,8 @@ impl Property for ExtData {
345
377
max_sat_size : self . max_sat_size ,
346
378
max_dissat_size : self . max_dissat_size ,
347
379
timelock_info : self . timelock_info ,
380
+ exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
381
+ exec_stack_elem_count_dissat : self . exec_stack_elem_count_dissat ,
348
382
} )
349
383
}
350
384
@@ -360,6 +394,8 @@ impl Property for ExtData {
360
394
max_sat_size : self . max_sat_size ,
361
395
max_dissat_size : self . max_dissat_size ,
362
396
timelock_info : self . timelock_info ,
397
+ exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
398
+ exec_stack_elem_count_dissat : self . exec_stack_elem_count_dissat ,
363
399
} )
364
400
}
365
401
@@ -375,6 +411,11 @@ impl Property for ExtData {
375
411
max_sat_size : self . max_sat_size . map ( |( w, s) | ( w + 2 , s + 1 ) ) ,
376
412
max_dissat_size : Some ( ( 1 , 1 ) ) ,
377
413
timelock_info : self . timelock_info ,
414
+ // Technically max(1, self.exec_stack_elem_count_sat), but all miniscript expressions
415
+ // that can be satisfied push at least one thing onto the stack.
416
+ // Even all V types push something onto the stack and then remove them
417
+ exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
418
+ exec_stack_elem_count_dissat : Some ( 1 ) ,
378
419
} )
379
420
}
380
421
@@ -391,6 +432,8 @@ impl Property for ExtData {
391
432
max_sat_size : self . max_sat_size ,
392
433
max_dissat_size : None ,
393
434
timelock_info : self . timelock_info ,
435
+ exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
436
+ exec_stack_elem_count_dissat : None ,
394
437
} )
395
438
}
396
439
@@ -406,6 +449,8 @@ impl Property for ExtData {
406
449
max_sat_size : self . max_sat_size ,
407
450
max_dissat_size : Some ( ( 1 , 1 ) ) ,
408
451
timelock_info : self . timelock_info ,
452
+ exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
453
+ exec_stack_elem_count_dissat : Some ( 1 ) ,
409
454
} )
410
455
}
411
456
@@ -421,6 +466,9 @@ impl Property for ExtData {
421
466
max_sat_size : self . max_sat_size ,
422
467
max_dissat_size : self . max_dissat_size ,
423
468
timelock_info : self . timelock_info ,
469
+ // Technically max(1, self.exec_stack_elem_count_sat), same rationale as cast_dupif
470
+ exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
471
+ exec_stack_elem_count_dissat : self . exec_stack_elem_count_dissat ,
424
472
} )
425
473
}
426
474
@@ -436,6 +484,9 @@ impl Property for ExtData {
436
484
max_sat_size : self . max_sat_size ,
437
485
max_dissat_size : None ,
438
486
timelock_info : self . timelock_info ,
487
+ // Technically max(1, self.exec_stack_elem_count_sat), same rationale as cast_dupif
488
+ exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
489
+ exec_stack_elem_count_dissat : self . exec_stack_elem_count_dissat ,
439
490
} )
440
491
}
441
492
@@ -455,6 +506,10 @@ impl Property for ExtData {
455
506
stack_elem_count_dissat : self . stack_elem_count_dissat . map ( |x| x + 1 ) ,
456
507
max_sat_size : self . max_sat_size . map ( |( w, s) | ( w + 2 , s + 1 ) ) ,
457
508
max_dissat_size : self . max_dissat_size . map ( |( w, s) | ( w + 1 , s + 1 ) ) ,
509
+ // TODO: fix dissat stack elem counting above in a later commit
510
+ // Technically max(1, self.exec_stack_elem_count_sat), same rationale as cast_dupif
511
+ exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
512
+ exec_stack_elem_count_dissat : self . exec_stack_elem_count_dissat ,
458
513
timelock_info : self . timelock_info ,
459
514
} )
460
515
}
@@ -471,6 +526,10 @@ impl Property for ExtData {
471
526
max_sat_size : self . max_sat_size . map ( |( w, s) | ( w + 1 , s + 1 ) ) ,
472
527
max_dissat_size : self . max_dissat_size . map ( |( w, s) | ( w + 2 , s + 1 ) ) ,
473
528
timelock_info : self . timelock_info ,
529
+ // TODO: fix dissat stack elem counting above in a later commit
530
+ // Technically max(1, self.exec_stack_elem_count_sat), same rationale as cast_dupif
531
+ exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
532
+ exec_stack_elem_count_dissat : self . exec_stack_elem_count_dissat ,
474
533
} )
475
534
}
476
535
@@ -498,6 +557,16 @@ impl Property for ExtData {
498
557
. max_dissat_size
499
558
. and_then ( |( lw, ls) | r. max_dissat_size . map ( |( rw, rs) | ( lw + rw, ls + rs) ) ) ,
500
559
timelock_info : TimeLockInfo :: comb_and_timelocks ( l. timelock_info , r. timelock_info ) ,
560
+ // Left element leaves a stack result on the stack top and then right element is evaluated
561
+ // Therefore + 1 is added to execution size of second element
562
+ exec_stack_elem_count_sat : cmp:: max (
563
+ l. exec_stack_elem_count_sat ,
564
+ r. exec_stack_elem_count_sat . map ( |x| x + 1 ) ,
565
+ ) ,
566
+ exec_stack_elem_count_dissat : cmp:: max (
567
+ l. exec_stack_elem_count_dissat ,
568
+ r. exec_stack_elem_count_dissat . map ( |x| x + 1 ) ,
569
+ ) ,
501
570
} )
502
571
}
503
572
@@ -517,6 +586,15 @@ impl Property for ExtData {
517
586
. and_then ( |( lw, ls) | r. max_sat_size . map ( |( rw, rs) | ( lw + rw, ls + rs) ) ) ,
518
587
max_dissat_size : None ,
519
588
timelock_info : TimeLockInfo :: comb_and_timelocks ( l. timelock_info , r. timelock_info ) ,
589
+ // [X] leaves no element after evaluation, hence this is the max
590
+ exec_stack_elem_count_sat : cmp:: max (
591
+ l. exec_stack_elem_count_sat ,
592
+ r. exec_stack_elem_count_sat ,
593
+ ) ,
594
+ exec_stack_elem_count_dissat : cmp:: max (
595
+ l. exec_stack_elem_count_dissat ,
596
+ r. exec_stack_elem_count_dissat ,
597
+ ) ,
520
598
} )
521
599
}
522
600
@@ -553,6 +631,20 @@ impl Property for ExtData {
553
631
. max_dissat_size
554
632
. and_then ( |( lw, ls) | r. max_dissat_size . map ( |( rw, rs) | ( lw + rw, ls + rs) ) ) ,
555
633
timelock_info : TimeLockInfo :: comb_or_timelocks ( l. timelock_info , r. timelock_info ) ,
634
+ exec_stack_elem_count_sat : cmp:: max (
635
+ cmp:: max (
636
+ l. exec_stack_elem_count_sat ,
637
+ r. exec_stack_elem_count_dissat . map ( |x| x + 1 ) ,
638
+ ) ,
639
+ cmp:: max (
640
+ l. exec_stack_elem_count_dissat ,
641
+ r. exec_stack_elem_count_sat . map ( |x| x + 1 ) ,
642
+ ) ,
643
+ ) ,
644
+ exec_stack_elem_count_dissat : cmp:: max (
645
+ l. exec_stack_elem_count_dissat ,
646
+ r. exec_stack_elem_count_dissat . map ( |x| x + 1 ) ,
647
+ ) ,
556
648
} )
557
649
}
558
650
@@ -586,6 +678,14 @@ impl Property for ExtData {
586
678
. max_dissat_size
587
679
. and_then ( |( lw, ls) | r. max_dissat_size . map ( |( rw, rs) | ( lw + rw, ls + rs) ) ) ,
588
680
timelock_info : TimeLockInfo :: comb_or_timelocks ( l. timelock_info , r. timelock_info ) ,
681
+ exec_stack_elem_count_sat : cmp:: max (
682
+ cmp:: max ( l. exec_stack_elem_count_sat , r. exec_stack_elem_count_dissat ) ,
683
+ r. exec_stack_elem_count_sat ,
684
+ ) ,
685
+ exec_stack_elem_count_dissat : cmp:: max (
686
+ l. exec_stack_elem_count_dissat ,
687
+ r. exec_stack_elem_count_dissat . map ( |x| x + 1 ) ,
688
+ ) ,
589
689
} )
590
690
}
591
691
@@ -613,6 +713,11 @@ impl Property for ExtData {
613
713
) ,
614
714
max_dissat_size : None ,
615
715
timelock_info : TimeLockInfo :: comb_or_timelocks ( l. timelock_info , r. timelock_info ) ,
716
+ exec_stack_elem_count_sat : cmp:: max (
717
+ cmp:: max ( l. exec_stack_elem_count_sat , r. exec_stack_elem_count_dissat ) ,
718
+ r. exec_stack_elem_count_sat ,
719
+ ) ,
720
+ exec_stack_elem_count_dissat : None ,
616
721
} )
617
722
}
618
723
@@ -656,6 +761,15 @@ impl Property for ExtData {
656
761
( None , None ) => None ,
657
762
} ,
658
763
timelock_info : TimeLockInfo :: comb_or_timelocks ( l. timelock_info , r. timelock_info ) ,
764
+ // TODO: fix elem count dissat bug
765
+ exec_stack_elem_count_sat : cmp:: max (
766
+ l. exec_stack_elem_count_sat ,
767
+ r. exec_stack_elem_count_sat ,
768
+ ) ,
769
+ exec_stack_elem_count_dissat : cmp:: max (
770
+ l. exec_stack_elem_count_dissat ,
771
+ r. exec_stack_elem_count_dissat ,
772
+ ) ,
659
773
} )
660
774
}
661
775
@@ -695,6 +809,14 @@ impl Property for ExtData {
695
809
TimeLockInfo :: comb_and_timelocks ( a. timelock_info , b. timelock_info ) ,
696
810
c. timelock_info ,
697
811
) ,
812
+ exec_stack_elem_count_sat : cmp:: max (
813
+ cmp:: max ( a. exec_stack_elem_count_sat , b. exec_stack_elem_count_sat ) ,
814
+ cmp:: max ( c. exec_stack_elem_count_sat , a. exec_stack_elem_count_dissat ) ,
815
+ ) ,
816
+ exec_stack_elem_count_dissat : cmp:: max (
817
+ a. exec_stack_elem_count_dissat ,
818
+ c. exec_stack_elem_count_dissat ,
819
+ ) ,
698
820
} )
699
821
}
700
822
@@ -716,6 +838,9 @@ impl Property for ExtData {
716
838
let mut max_sat_size_vec = Vec :: with_capacity ( n) ;
717
839
let mut max_sat_size = Some ( ( 0 , 0 ) ) ;
718
840
let mut max_dissat_size = Some ( ( 0 , 0 ) ) ;
841
+ // the max element count is same as max sat element count when satisfying one element + 1
842
+ let mut exec_stack_elem_count_sat = None ;
843
+ let mut exec_stack_elem_count_dissat = None ;
719
844
720
845
for i in 0 ..n {
721
846
let sub = sub_ck ( i) ?;
@@ -751,6 +876,17 @@ impl Property for ExtData {
751
876
}
752
877
_ => { }
753
878
}
879
+ // Threshold satisfaction require satisfaction/disssat of each child
880
+ // Therefore, the max count is max of children + 1 (for the previous result)
881
+ exec_stack_elem_count_sat =
882
+ cmp:: max ( exec_stack_elem_count_sat, sub. exec_stack_elem_count_sat ) ;
883
+ // satisfaction involve dissatisfactions too
884
+ exec_stack_elem_count_sat =
885
+ cmp:: max ( exec_stack_elem_count_sat, sub. exec_stack_elem_count_dissat ) ;
886
+ exec_stack_elem_count_dissat = cmp:: max (
887
+ exec_stack_elem_count_dissat,
888
+ sub. exec_stack_elem_count_dissat ,
889
+ ) ;
754
890
}
755
891
756
892
// We sort by [satisfaction cost - dissatisfaction cost] to make a worst-case (the most
@@ -809,6 +945,8 @@ impl Property for ExtData {
809
945
max_sat_size,
810
946
max_dissat_size,
811
947
timelock_info : TimeLockInfo :: combine_thresh_timelocks ( k, timelocks) ,
948
+ exec_stack_elem_count_sat,
949
+ exec_stack_elem_count_dissat,
812
950
} )
813
951
}
814
952
0 commit comments