@@ -119,6 +119,14 @@ pub struct ExtData {
119119 pub max_dissat_size : Option < ( usize , usize ) > ,
120120 /// The timelock info about heightlocks and timelocks
121121 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 > ,
122130}
123131
124132impl Property for ExtData {
@@ -138,6 +146,8 @@ impl Property for ExtData {
138146 max_sat_size : Some ( ( 0 , 0 ) ) ,
139147 max_dissat_size : None ,
140148 timelock_info : TimeLockInfo :: default ( ) ,
149+ exec_stack_elem_count_sat : Some ( 1 ) ,
150+ exec_stack_elem_count_dissat : None ,
141151 }
142152 }
143153
@@ -153,6 +163,8 @@ impl Property for ExtData {
153163 max_sat_size : None ,
154164 max_dissat_size : Some ( ( 0 , 0 ) ) ,
155165 timelock_info : TimeLockInfo :: default ( ) ,
166+ exec_stack_elem_count_sat : None ,
167+ exec_stack_elem_count_dissat : Some ( 1 ) ,
156168 }
157169 }
158170
@@ -168,6 +180,8 @@ impl Property for ExtData {
168180 max_sat_size : Some ( ( 73 , 73 ) ) ,
169181 max_dissat_size : Some ( ( 1 , 1 ) ) ,
170182 timelock_info : TimeLockInfo :: default ( ) ,
183+ exec_stack_elem_count_sat : Some ( 1 ) , // pushes the pk
184+ exec_stack_elem_count_dissat : Some ( 1 ) ,
171185 }
172186 }
173187
@@ -183,6 +197,8 @@ impl Property for ExtData {
183197 max_sat_size : Some ( ( 34 + 73 , 34 + 73 ) ) ,
184198 max_dissat_size : Some ( ( 35 , 35 ) ) ,
185199 timelock_info : TimeLockInfo :: default ( ) ,
200+ exec_stack_elem_count_sat : Some ( 2 ) , // dup and hash push
201+ exec_stack_elem_count_dissat : Some ( 2 ) ,
186202 }
187203 }
188204
@@ -204,6 +220,8 @@ impl Property for ExtData {
204220 max_sat_size : Some ( ( 1 + 73 * k, 1 + 73 * k) ) ,
205221 max_dissat_size : Some ( ( 1 + k, 1 + k) ) ,
206222 timelock_info : TimeLockInfo :: default ( ) ,
223+ exec_stack_elem_count_sat : Some ( n) , // n pks
224+ exec_stack_elem_count_dissat : Some ( n) ,
207225 }
208226 }
209227
@@ -224,6 +242,8 @@ impl Property for ExtData {
224242 max_sat_size : Some ( ( 33 , 33 ) ) ,
225243 max_dissat_size : Some ( ( 33 , 33 ) ) ,
226244 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 ) ,
227247 }
228248 }
229249
@@ -239,6 +259,8 @@ impl Property for ExtData {
239259 max_sat_size : Some ( ( 33 , 33 ) ) ,
240260 max_dissat_size : Some ( ( 33 , 33 ) ) ,
241261 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 ) ,
242264 }
243265 }
244266
@@ -254,6 +276,8 @@ impl Property for ExtData {
254276 max_sat_size : Some ( ( 33 , 33 ) ) ,
255277 max_dissat_size : Some ( ( 33 , 33 ) ) ,
256278 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 ) ,
257281 }
258282 }
259283
@@ -269,6 +293,8 @@ impl Property for ExtData {
269293 max_sat_size : Some ( ( 33 , 33 ) ) ,
270294 max_dissat_size : Some ( ( 33 , 33 ) ) ,
271295 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 ) ,
272298 }
273299 }
274300
@@ -294,6 +320,8 @@ impl Property for ExtData {
294320 cltv_with_time : t >= HEIGHT_TIME_THRESHOLD ,
295321 contains_combination : false ,
296322 } ,
323+ exec_stack_elem_count_sat : Some ( 1 ) , // <t>
324+ exec_stack_elem_count_dissat : None ,
297325 }
298326 }
299327
@@ -315,6 +343,8 @@ impl Property for ExtData {
315343 cltv_with_time : false ,
316344 contains_combination : false ,
317345 } ,
346+ exec_stack_elem_count_sat : Some ( 1 ) , // <t>
347+ exec_stack_elem_count_dissat : None ,
318348 }
319349 }
320350
@@ -330,6 +360,8 @@ impl Property for ExtData {
330360 max_sat_size : self . max_sat_size ,
331361 max_dissat_size : self . max_dissat_size ,
332362 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 ,
333365 } )
334366 }
335367
@@ -345,6 +377,8 @@ impl Property for ExtData {
345377 max_sat_size : self . max_sat_size ,
346378 max_dissat_size : self . max_dissat_size ,
347379 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 ,
348382 } )
349383 }
350384
@@ -360,6 +394,8 @@ impl Property for ExtData {
360394 max_sat_size : self . max_sat_size ,
361395 max_dissat_size : self . max_dissat_size ,
362396 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 ,
363399 } )
364400 }
365401
@@ -375,6 +411,11 @@ impl Property for ExtData {
375411 max_sat_size : self . max_sat_size . map ( |( w, s) | ( w + 2 , s + 1 ) ) ,
376412 max_dissat_size : Some ( ( 1 , 1 ) ) ,
377413 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 ) ,
378419 } )
379420 }
380421
@@ -391,6 +432,8 @@ impl Property for ExtData {
391432 max_sat_size : self . max_sat_size ,
392433 max_dissat_size : None ,
393434 timelock_info : self . timelock_info ,
435+ exec_stack_elem_count_sat : self . exec_stack_elem_count_sat ,
436+ exec_stack_elem_count_dissat : None ,
394437 } )
395438 }
396439
@@ -406,6 +449,8 @@ impl Property for ExtData {
406449 max_sat_size : self . max_sat_size ,
407450 max_dissat_size : Some ( ( 1 , 1 ) ) ,
408451 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 ) ,
409454 } )
410455 }
411456
@@ -421,6 +466,9 @@ impl Property for ExtData {
421466 max_sat_size : self . max_sat_size ,
422467 max_dissat_size : self . max_dissat_size ,
423468 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 ,
424472 } )
425473 }
426474
@@ -436,6 +484,9 @@ impl Property for ExtData {
436484 max_sat_size : self . max_sat_size ,
437485 max_dissat_size : None ,
438486 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 ,
439490 } )
440491 }
441492
@@ -455,6 +506,10 @@ impl Property for ExtData {
455506 stack_elem_count_dissat : self . stack_elem_count_dissat . map ( |x| x + 1 ) ,
456507 max_sat_size : self . max_sat_size . map ( |( w, s) | ( w + 2 , s + 1 ) ) ,
457508 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 ,
458513 timelock_info : self . timelock_info ,
459514 } )
460515 }
@@ -471,6 +526,10 @@ impl Property for ExtData {
471526 max_sat_size : self . max_sat_size . map ( |( w, s) | ( w + 1 , s + 1 ) ) ,
472527 max_dissat_size : self . max_dissat_size . map ( |( w, s) | ( w + 2 , s + 1 ) ) ,
473528 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 ,
474533 } )
475534 }
476535
@@ -498,6 +557,16 @@ impl Property for ExtData {
498557 . max_dissat_size
499558 . and_then ( |( lw, ls) | r. max_dissat_size . map ( |( rw, rs) | ( lw + rw, ls + rs) ) ) ,
500559 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+ ) ,
501570 } )
502571 }
503572
@@ -517,6 +586,15 @@ impl Property for ExtData {
517586 . and_then ( |( lw, ls) | r. max_sat_size . map ( |( rw, rs) | ( lw + rw, ls + rs) ) ) ,
518587 max_dissat_size : None ,
519588 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+ ) ,
520598 } )
521599 }
522600
@@ -553,6 +631,20 @@ impl Property for ExtData {
553631 . max_dissat_size
554632 . and_then ( |( lw, ls) | r. max_dissat_size . map ( |( rw, rs) | ( lw + rw, ls + rs) ) ) ,
555633 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+ ) ,
556648 } )
557649 }
558650
@@ -586,6 +678,14 @@ impl Property for ExtData {
586678 . max_dissat_size
587679 . and_then ( |( lw, ls) | r. max_dissat_size . map ( |( rw, rs) | ( lw + rw, ls + rs) ) ) ,
588680 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+ ) ,
589689 } )
590690 }
591691
@@ -613,6 +713,11 @@ impl Property for ExtData {
613713 ) ,
614714 max_dissat_size : None ,
615715 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 ,
616721 } )
617722 }
618723
@@ -656,6 +761,15 @@ impl Property for ExtData {
656761 ( None , None ) => None ,
657762 } ,
658763 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+ ) ,
659773 } )
660774 }
661775
@@ -695,6 +809,14 @@ impl Property for ExtData {
695809 TimeLockInfo :: comb_and_timelocks ( a. timelock_info , b. timelock_info ) ,
696810 c. timelock_info ,
697811 ) ,
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+ ) ,
698820 } )
699821 }
700822
@@ -716,6 +838,9 @@ impl Property for ExtData {
716838 let mut max_sat_size_vec = Vec :: with_capacity ( n) ;
717839 let mut max_sat_size = Some ( ( 0 , 0 ) ) ;
718840 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 ;
719844
720845 for i in 0 ..n {
721846 let sub = sub_ck ( i) ?;
@@ -751,6 +876,17 @@ impl Property for ExtData {
751876 }
752877 _ => { }
753878 }
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+ ) ;
754890 }
755891
756892 // We sort by [satisfaction cost - dissatisfaction cost] to make a worst-case (the most
@@ -809,6 +945,8 @@ impl Property for ExtData {
809945 max_sat_size,
810946 max_dissat_size,
811947 timelock_info : TimeLockInfo :: combine_thresh_timelocks ( k, timelocks) ,
948+ exec_stack_elem_count_sat,
949+ exec_stack_elem_count_dissat,
812950 } )
813951 }
814952
0 commit comments