@@ -220,6 +220,12 @@ where
220
220
Ok ( ( ) )
221
221
}
222
222
223
+ /// Each context has slightly different rules on what Pks are allowed in descriptors
224
+ /// Legacy/Bare does not allow x_only keys
225
+ /// Segwit does not allow uncompressed keys and x_only keys
226
+ /// Tapscript does not allow uncompressed keys
227
+ fn check_pk < Pk : MiniscriptKey > ( pk : & Pk ) -> Result < ( ) , ScriptContextError > ;
228
+
223
229
/// Depending on script context, the size of a satifaction witness may slightly differ.
224
230
fn max_satisfaction_size < Pk : MiniscriptKey > ( ms : & Miniscript < Pk , Self > ) -> Option < usize > ;
225
231
/// Depending on script Context, some of the Terminals might not
@@ -367,6 +373,18 @@ impl ScriptContext for Legacy {
367
373
}
368
374
}
369
375
376
+ // Only compressed and uncompressed public keys are allowed in Legacy context
377
+ fn check_pk < Pk : MiniscriptKey > ( pk : & Pk ) -> Result < ( ) , ScriptContextError > {
378
+ if pk. is_x_only_key ( ) {
379
+ Err ( ScriptContextError :: XOnlyKeysNotAllowed (
380
+ pk. to_string ( ) ,
381
+ Self :: name_str ( ) ,
382
+ ) )
383
+ } else {
384
+ Ok ( ( ) )
385
+ }
386
+ }
387
+
370
388
fn check_witness < Pk : MiniscriptKey > ( witness : & [ Vec < u8 > ] ) -> Result < ( ) , ScriptContextError > {
371
389
// In future, we could avoid by having a function to count only
372
390
// len of script instead of converting it.
@@ -384,31 +402,21 @@ impl ScriptContext for Legacy {
384
402
}
385
403
386
404
match ms. node {
387
- Terminal :: PkK ( ref key) if key. is_x_only_key ( ) => {
388
- return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
389
- key. to_string ( ) ,
390
- Self :: name_str ( ) ,
391
- ) )
392
- }
405
+ Terminal :: PkK ( ref pk) => Self :: check_pk ( pk) ,
393
406
Terminal :: Multi ( _k, ref pks) => {
394
407
if pks. len ( ) > MAX_PUBKEYS_PER_MULTISIG {
395
408
return Err ( ScriptContextError :: CheckMultiSigLimitExceeded ) ;
396
409
}
397
410
for pk in pks. iter ( ) {
398
- if pk. is_x_only_key ( ) {
399
- return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
400
- pk. to_string ( ) ,
401
- Self :: name_str ( ) ,
402
- ) ) ;
403
- }
411
+ Self :: check_pk ( pk) ?;
404
412
}
413
+ Ok ( ( ) )
405
414
}
406
415
Terminal :: MultiA ( ..) => {
407
416
return Err ( ScriptContextError :: MultiANotAllowed ) ;
408
417
}
409
- _ => { }
418
+ _ => Ok ( ( ) ) ,
410
419
}
411
- Ok ( ( ) )
412
420
}
413
421
414
422
fn check_local_consensus_validity < Pk : MiniscriptKey > (
@@ -472,6 +480,20 @@ impl ScriptContext for Segwitv0 {
472
480
Ok ( ( ) )
473
481
}
474
482
483
+ // No x-only keys or uncompressed keys in Segwitv0 context
484
+ fn check_pk < Pk : MiniscriptKey > ( pk : & Pk ) -> Result < ( ) , ScriptContextError > {
485
+ if pk. is_uncompressed ( ) {
486
+ Err ( ScriptContextError :: UncompressedKeysNotAllowed )
487
+ } else if pk. is_x_only_key ( ) {
488
+ Err ( ScriptContextError :: XOnlyKeysNotAllowed (
489
+ pk. to_string ( ) ,
490
+ Self :: name_str ( ) ,
491
+ ) )
492
+ } else {
493
+ Ok ( ( ) )
494
+ }
495
+ }
496
+
475
497
fn check_witness < Pk : MiniscriptKey > ( witness : & [ Vec < u8 > ] ) -> Result < ( ) , ScriptContextError > {
476
498
if witness. len ( ) > MAX_STANDARD_P2WSH_STACK_ITEMS {
477
499
return Err ( ScriptContextError :: MaxWitnessItemssExceeded {
@@ -490,30 +512,13 @@ impl ScriptContext for Segwitv0 {
490
512
}
491
513
492
514
match ms. node {
493
- Terminal :: PkK ( ref pk) => {
494
- if pk. is_uncompressed ( ) {
495
- return Err ( ScriptContextError :: CompressedOnly ( pk. to_string ( ) ) ) ;
496
- } else if pk. is_x_only_key ( ) {
497
- return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
498
- pk. to_string ( ) ,
499
- Self :: name_str ( ) ,
500
- ) ) ;
501
- }
502
- Ok ( ( ) )
503
- }
515
+ Terminal :: PkK ( ref pk) => Self :: check_pk ( pk) ,
504
516
Terminal :: Multi ( _k, ref pks) => {
505
517
if pks. len ( ) > MAX_PUBKEYS_PER_MULTISIG {
506
518
return Err ( ScriptContextError :: CheckMultiSigLimitExceeded ) ;
507
519
}
508
520
for pk in pks. iter ( ) {
509
- if pk. is_uncompressed ( ) {
510
- return Err ( ScriptContextError :: CompressedOnly ( pk. to_string ( ) ) ) ;
511
- } else if pk. is_x_only_key ( ) {
512
- return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
513
- pk. to_string ( ) ,
514
- Self :: name_str ( ) ,
515
- ) ) ;
516
- }
521
+ Self :: check_pk ( pk) ?;
517
522
}
518
523
Ok ( ( ) )
519
524
}
@@ -594,6 +599,15 @@ impl ScriptContext for Tap {
594
599
Ok ( ( ) )
595
600
}
596
601
602
+ // No uncompressed keys in Tap context
603
+ fn check_pk < Pk : MiniscriptKey > ( pk : & Pk ) -> Result < ( ) , ScriptContextError > {
604
+ if pk. is_uncompressed ( ) {
605
+ Err ( ScriptContextError :: UncompressedKeysNotAllowed )
606
+ } else {
607
+ Ok ( ( ) )
608
+ }
609
+ }
610
+
597
611
fn check_witness < Pk : MiniscriptKey > ( witness : & [ Vec < u8 > ] ) -> Result < ( ) , ScriptContextError > {
598
612
// Note that tapscript has a 1000 limit compared to 100 of segwitv0
599
613
if witness. len ( ) > MAX_STACK_SIZE {
@@ -618,9 +632,10 @@ impl ScriptContext for Tap {
618
632
}
619
633
620
634
match ms. node {
621
- Terminal :: PkK ( ref pk) => {
622
- if pk. is_uncompressed ( ) {
623
- return Err ( ScriptContextError :: UncompressedKeysNotAllowed ) ;
635
+ Terminal :: PkK ( ref pk) => Self :: check_pk ( pk) ,
636
+ Terminal :: MultiA ( _, ref keys) => {
637
+ for pk in keys. iter ( ) {
638
+ Self :: check_pk ( pk) ?;
624
639
}
625
640
Ok ( ( ) )
626
641
}
@@ -705,30 +720,32 @@ impl ScriptContext for BareCtx {
705
720
Ok ( ( ) )
706
721
}
707
722
723
+ // No x-only keys in Bare context
724
+ fn check_pk < Pk : MiniscriptKey > ( pk : & Pk ) -> Result < ( ) , ScriptContextError > {
725
+ if pk. is_x_only_key ( ) {
726
+ Err ( ScriptContextError :: XOnlyKeysNotAllowed (
727
+ pk. to_string ( ) ,
728
+ Self :: name_str ( ) ,
729
+ ) )
730
+ } else {
731
+ Ok ( ( ) )
732
+ }
733
+ }
734
+
708
735
fn check_global_consensus_validity < Pk : MiniscriptKey > (
709
736
ms : & Miniscript < Pk , Self > ,
710
737
) -> Result < ( ) , ScriptContextError > {
711
738
if ms. ext . pk_cost > MAX_SCRIPT_SIZE {
712
739
return Err ( ScriptContextError :: MaxWitnessScriptSizeExceeded ) ;
713
740
}
714
741
match ms. node {
715
- Terminal :: PkK ( ref key) if key. is_x_only_key ( ) => {
716
- return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
717
- key. to_string ( ) ,
718
- Self :: name_str ( ) ,
719
- ) )
720
- }
742
+ Terminal :: PkK ( ref key) => Self :: check_pk ( key) ,
721
743
Terminal :: Multi ( _k, ref pks) => {
722
744
if pks. len ( ) > MAX_PUBKEYS_PER_MULTISIG {
723
745
return Err ( ScriptContextError :: CheckMultiSigLimitExceeded ) ;
724
746
}
725
747
for pk in pks. iter ( ) {
726
- if pk. is_x_only_key ( ) {
727
- return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
728
- pk. to_string ( ) ,
729
- Self :: name_str ( ) ,
730
- ) ) ;
731
- }
748
+ Self :: check_pk ( pk) ?;
732
749
}
733
750
Ok ( ( ) )
734
751
}
@@ -799,6 +816,11 @@ impl ScriptContext for NoChecks {
799
816
Ok ( ( ) )
800
817
}
801
818
819
+ // No checks in NoChecks
820
+ fn check_pk < Pk : MiniscriptKey > ( _pk : & Pk ) -> Result < ( ) , ScriptContextError > {
821
+ Ok ( ( ) )
822
+ }
823
+
802
824
fn check_global_policy_validity < Pk : MiniscriptKey > (
803
825
_ms : & Miniscript < Pk , Self > ,
804
826
) -> Result < ( ) , ScriptContextError > {
0 commit comments