@@ -394,11 +394,8 @@ impl ScriptContext for Legacy {
394
394
fn check_global_consensus_validity < Pk : MiniscriptKey > (
395
395
ms : & Miniscript < Pk , Self > ,
396
396
) -> Result < ( ) , ScriptContextError > {
397
- if ms. ext . pk_cost > MAX_SCRIPT_ELEMENT_SIZE {
398
- return Err ( ScriptContextError :: MaxRedeemScriptSizeExceeded ) ;
399
- }
400
-
401
- match ms. node {
397
+ // 1. Check the node first, throw an error on the language itself
398
+ let node_checked = match ms. node {
402
399
Terminal :: PkK ( ref pk) => Self :: check_pk ( pk) ,
403
400
Terminal :: Multi ( ref thresh) => {
404
401
for pk in thresh. iter ( ) {
@@ -408,6 +405,17 @@ impl ScriptContext for Legacy {
408
405
}
409
406
Terminal :: MultiA ( ..) => Err ( ScriptContextError :: MultiANotAllowed ) ,
410
407
_ => Ok ( ( ) ) ,
408
+ } ;
409
+ // 2. After fragment and param check, validate the script size finally
410
+ match node_checked {
411
+ Ok ( _) => {
412
+ if ms. ext . pk_cost > MAX_SCRIPT_ELEMENT_SIZE {
413
+ Err ( ScriptContextError :: MaxRedeemScriptSizeExceeded )
414
+ } else {
415
+ Ok ( ( ) )
416
+ }
417
+ }
418
+ Err ( _) => node_checked,
411
419
}
412
420
}
413
421
@@ -492,11 +500,8 @@ impl ScriptContext for Segwitv0 {
492
500
fn check_global_consensus_validity < Pk : MiniscriptKey > (
493
501
ms : & Miniscript < Pk , Self > ,
494
502
) -> Result < ( ) , ScriptContextError > {
495
- if ms. ext . pk_cost > MAX_SCRIPT_SIZE {
496
- return Err ( ScriptContextError :: MaxWitnessScriptSizeExceeded ) ;
497
- }
498
-
499
- match ms. node {
503
+ // 1. Check the node first, throw an error on the language itself
504
+ let node_checked = match ms. node {
500
505
Terminal :: PkK ( ref pk) => Self :: check_pk ( pk) ,
501
506
Terminal :: Multi ( ref thresh) => {
502
507
for pk in thresh. iter ( ) {
@@ -506,6 +511,17 @@ impl ScriptContext for Segwitv0 {
506
511
}
507
512
Terminal :: MultiA ( ..) => Err ( ScriptContextError :: MultiANotAllowed ) ,
508
513
_ => Ok ( ( ) ) ,
514
+ } ;
515
+ // 2. After fragment and param check, validate the script size finally
516
+ match node_checked {
517
+ Ok ( _) => {
518
+ if ms. ext . pk_cost > MAX_SCRIPT_SIZE {
519
+ Err ( ScriptContextError :: MaxWitnessScriptSizeExceeded )
520
+ } else {
521
+ Ok ( ( ) )
522
+ }
523
+ }
524
+ Err ( _) => node_checked,
509
525
}
510
526
}
511
527
@@ -598,16 +614,8 @@ impl ScriptContext for Tap {
598
614
fn check_global_consensus_validity < Pk : MiniscriptKey > (
599
615
ms : & Miniscript < Pk , Self > ,
600
616
) -> Result < ( ) , ScriptContextError > {
601
- // No script size checks for global consensus rules
602
- // Should we really check for block limits here.
603
- // When the transaction sizes get close to block limits,
604
- // some guarantees are not easy to satisfy because of knapsack
605
- // constraints
606
- if ms. ext . pk_cost as u64 > Weight :: MAX_BLOCK . to_wu ( ) {
607
- return Err ( ScriptContextError :: MaxWitnessScriptSizeExceeded ) ;
608
- }
609
-
610
- match ms. node {
617
+ // 1. Check the node first, throw an error on the language itself
618
+ let node_checked = match ms. node {
611
619
Terminal :: PkK ( ref pk) => Self :: check_pk ( pk) ,
612
620
Terminal :: MultiA ( ref thresh) => {
613
621
for pk in thresh. iter ( ) {
@@ -617,6 +625,22 @@ impl ScriptContext for Tap {
617
625
}
618
626
Terminal :: Multi ( ..) => Err ( ScriptContextError :: TaprootMultiDisabled ) ,
619
627
_ => Ok ( ( ) ) ,
628
+ } ;
629
+ // 2. After fragment and param check, validate the script size finally
630
+ match node_checked {
631
+ Ok ( _) => {
632
+ // No script size checks for global consensus rules
633
+ // Should we really check for block limits here.
634
+ // When the transaction sizes get close to block limits,
635
+ // some guarantees are not easy to satisfy because of knapsack
636
+ // constraints
637
+ if ms. ext . pk_cost as u64 > Weight :: MAX_BLOCK . to_wu ( ) {
638
+ Err ( ScriptContextError :: MaxWitnessScriptSizeExceeded )
639
+ } else {
640
+ Ok ( ( ) )
641
+ }
642
+ }
643
+ Err ( _) => node_checked,
620
644
}
621
645
}
622
646
@@ -700,10 +724,8 @@ impl ScriptContext for BareCtx {
700
724
fn check_global_consensus_validity < Pk : MiniscriptKey > (
701
725
ms : & Miniscript < Pk , Self > ,
702
726
) -> Result < ( ) , ScriptContextError > {
703
- if ms. ext . pk_cost > MAX_SCRIPT_SIZE {
704
- return Err ( ScriptContextError :: MaxWitnessScriptSizeExceeded ) ;
705
- }
706
- match ms. node {
727
+ // 1. Check the node first, throw an error on the language itself
728
+ let node_checked = match ms. node {
707
729
Terminal :: PkK ( ref key) => Self :: check_pk ( key) ,
708
730
Terminal :: Multi ( ref thresh) => {
709
731
for pk in thresh. iter ( ) {
@@ -713,6 +735,17 @@ impl ScriptContext for BareCtx {
713
735
}
714
736
Terminal :: MultiA ( ..) => Err ( ScriptContextError :: MultiANotAllowed ) ,
715
737
_ => Ok ( ( ) ) ,
738
+ } ;
739
+ // 2. After fragment and param check, validate the script size finally
740
+ match node_checked {
741
+ Ok ( _) => {
742
+ if ms. ext . pk_cost > MAX_SCRIPT_SIZE {
743
+ Err ( ScriptContextError :: MaxWitnessScriptSizeExceeded )
744
+ } else {
745
+ Ok ( ( ) )
746
+ }
747
+ }
748
+ Err ( _) => node_checked,
716
749
}
717
750
}
718
751
0 commit comments