@@ -208,6 +208,12 @@ where
208
208
Ok ( ( ) )
209
209
}
210
210
211
+ /// Each context has slightly different rules on what Pks are allowed in descriptors
212
+ /// Legacy/Bare does not allow x_only keys
213
+ /// Segwit does not allow uncompressed keys and x_only keys
214
+ /// Tapscript does not allow uncompressed keys
215
+ fn check_pk < Pk : MiniscriptKey > ( pk : & Pk ) -> Result < ( ) , ScriptContextError > ;
216
+
211
217
/// Depending on script context, the size of a satifaction witness may slightly differ.
212
218
fn max_satisfaction_size < Pk : MiniscriptKey > ( ms : & Miniscript < Pk , Self > ) -> Option < usize > ;
213
219
/// Depending on script Context, some of the Terminals might not
@@ -355,6 +361,18 @@ impl ScriptContext for Legacy {
355
361
}
356
362
}
357
363
364
+ // Only compressed and uncompressed public keys are allowed in Legacy context
365
+ fn check_pk < Pk : MiniscriptKey > ( pk : & Pk ) -> Result < ( ) , ScriptContextError > {
366
+ if pk. is_x_only_key ( ) {
367
+ Err ( ScriptContextError :: XOnlyKeysNotAllowed (
368
+ pk. to_string ( ) ,
369
+ Self :: name_str ( ) ,
370
+ ) )
371
+ } else {
372
+ Ok ( ( ) )
373
+ }
374
+ }
375
+
358
376
fn check_witness < Pk : MiniscriptKey > ( witness : & [ Vec < u8 > ] ) -> Result < ( ) , ScriptContextError > {
359
377
// In future, we could avoid by having a function to count only
360
378
// len of script instead of converting it.
@@ -372,31 +390,21 @@ impl ScriptContext for Legacy {
372
390
}
373
391
374
392
match ms. node {
375
- Terminal :: PkK ( ref key) if key. is_x_only_key ( ) => {
376
- return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
377
- key. to_string ( ) ,
378
- Self :: name_str ( ) ,
379
- ) )
380
- }
393
+ Terminal :: PkK ( ref pk) => Self :: check_pk ( pk) ,
381
394
Terminal :: Multi ( _k, ref pks) => {
382
395
if pks. len ( ) > MAX_PUBKEYS_PER_MULTISIG {
383
396
return Err ( ScriptContextError :: CheckMultiSigLimitExceeded ) ;
384
397
}
385
398
for pk in pks. iter ( ) {
386
- if pk. is_x_only_key ( ) {
387
- return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
388
- pk. to_string ( ) ,
389
- Self :: name_str ( ) ,
390
- ) ) ;
391
- }
399
+ Self :: check_pk ( pk) ?;
392
400
}
401
+ Ok ( ( ) )
393
402
}
394
403
Terminal :: MultiA ( ..) => {
395
404
return Err ( ScriptContextError :: MultiANotAllowed ) ;
396
405
}
397
- _ => { }
406
+ _ => Ok ( ( ) ) ,
398
407
}
399
- Ok ( ( ) )
400
408
}
401
409
402
410
fn check_local_consensus_validity < Pk : MiniscriptKey > (
@@ -460,6 +468,20 @@ impl ScriptContext for Segwitv0 {
460
468
Ok ( ( ) )
461
469
}
462
470
471
+ // No x-only keys or uncompressed keys in Segwitv0 context
472
+ fn check_pk < Pk : MiniscriptKey > ( pk : & Pk ) -> Result < ( ) , ScriptContextError > {
473
+ if pk. is_uncompressed ( ) {
474
+ Err ( ScriptContextError :: UncompressedKeysNotAllowed )
475
+ } else if pk. is_x_only_key ( ) {
476
+ Err ( ScriptContextError :: XOnlyKeysNotAllowed (
477
+ pk. to_string ( ) ,
478
+ Self :: name_str ( ) ,
479
+ ) )
480
+ } else {
481
+ Ok ( ( ) )
482
+ }
483
+ }
484
+
463
485
fn check_witness < Pk : MiniscriptKey > ( witness : & [ Vec < u8 > ] ) -> Result < ( ) , ScriptContextError > {
464
486
if witness. len ( ) > MAX_STANDARD_P2WSH_STACK_ITEMS {
465
487
return Err ( ScriptContextError :: MaxWitnessItemssExceeded {
@@ -478,30 +500,13 @@ impl ScriptContext for Segwitv0 {
478
500
}
479
501
480
502
match ms. node {
481
- Terminal :: PkK ( ref pk) => {
482
- if pk. is_uncompressed ( ) {
483
- return Err ( ScriptContextError :: CompressedOnly ( pk. to_string ( ) ) ) ;
484
- } else if pk. is_x_only_key ( ) {
485
- return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
486
- pk. to_string ( ) ,
487
- Self :: name_str ( ) ,
488
- ) ) ;
489
- }
490
- Ok ( ( ) )
491
- }
503
+ Terminal :: PkK ( ref pk) => Self :: check_pk ( pk) ,
492
504
Terminal :: Multi ( _k, ref pks) => {
493
505
if pks. len ( ) > MAX_PUBKEYS_PER_MULTISIG {
494
506
return Err ( ScriptContextError :: CheckMultiSigLimitExceeded ) ;
495
507
}
496
508
for pk in pks. iter ( ) {
497
- if pk. is_uncompressed ( ) {
498
- return Err ( ScriptContextError :: CompressedOnly ( pk. to_string ( ) ) ) ;
499
- } else if pk. is_x_only_key ( ) {
500
- return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
501
- pk. to_string ( ) ,
502
- Self :: name_str ( ) ,
503
- ) ) ;
504
- }
509
+ Self :: check_pk ( pk) ?;
505
510
}
506
511
Ok ( ( ) )
507
512
}
@@ -582,6 +587,15 @@ impl ScriptContext for Tap {
582
587
Ok ( ( ) )
583
588
}
584
589
590
+ // No uncompressed keys in Tap context
591
+ fn check_pk < Pk : MiniscriptKey > ( pk : & Pk ) -> Result < ( ) , ScriptContextError > {
592
+ if pk. is_uncompressed ( ) {
593
+ Err ( ScriptContextError :: UncompressedKeysNotAllowed )
594
+ } else {
595
+ Ok ( ( ) )
596
+ }
597
+ }
598
+
585
599
fn check_witness < Pk : MiniscriptKey > ( witness : & [ Vec < u8 > ] ) -> Result < ( ) , ScriptContextError > {
586
600
// Note that tapscript has a 1000 limit compared to 100 of segwitv0
587
601
if witness. len ( ) > MAX_STACK_SIZE {
@@ -606,9 +620,10 @@ impl ScriptContext for Tap {
606
620
}
607
621
608
622
match ms. node {
609
- Terminal :: PkK ( ref pk) => {
610
- if pk. is_uncompressed ( ) {
611
- return Err ( ScriptContextError :: UncompressedKeysNotAllowed ) ;
623
+ Terminal :: PkK ( ref pk) => Self :: check_pk ( pk) ,
624
+ Terminal :: MultiA ( _, ref keys) => {
625
+ for pk in keys. iter ( ) {
626
+ Self :: check_pk ( pk) ?;
612
627
}
613
628
Ok ( ( ) )
614
629
}
@@ -693,30 +708,32 @@ impl ScriptContext for BareCtx {
693
708
Ok ( ( ) )
694
709
}
695
710
711
+ // No x-only keys in Bare context
712
+ fn check_pk < Pk : MiniscriptKey > ( pk : & Pk ) -> Result < ( ) , ScriptContextError > {
713
+ if pk. is_x_only_key ( ) {
714
+ Err ( ScriptContextError :: XOnlyKeysNotAllowed (
715
+ pk. to_string ( ) ,
716
+ Self :: name_str ( ) ,
717
+ ) )
718
+ } else {
719
+ Ok ( ( ) )
720
+ }
721
+ }
722
+
696
723
fn check_global_consensus_validity < Pk : MiniscriptKey > (
697
724
ms : & Miniscript < Pk , Self > ,
698
725
) -> Result < ( ) , ScriptContextError > {
699
726
if ms. ext . pk_cost > MAX_SCRIPT_SIZE {
700
727
return Err ( ScriptContextError :: MaxWitnessScriptSizeExceeded ) ;
701
728
}
702
729
match ms. node {
703
- Terminal :: PkK ( ref key) if key. is_x_only_key ( ) => {
704
- return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
705
- key. to_string ( ) ,
706
- Self :: name_str ( ) ,
707
- ) )
708
- }
730
+ Terminal :: PkK ( ref key) => Self :: check_pk ( key) ,
709
731
Terminal :: Multi ( _k, ref pks) => {
710
732
if pks. len ( ) > MAX_PUBKEYS_PER_MULTISIG {
711
733
return Err ( ScriptContextError :: CheckMultiSigLimitExceeded ) ;
712
734
}
713
735
for pk in pks. iter ( ) {
714
- if pk. is_x_only_key ( ) {
715
- return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
716
- pk. to_string ( ) ,
717
- Self :: name_str ( ) ,
718
- ) ) ;
719
- }
736
+ Self :: check_pk ( pk) ?;
720
737
}
721
738
Ok ( ( ) )
722
739
}
@@ -787,6 +804,11 @@ impl ScriptContext for NoChecks {
787
804
Ok ( ( ) )
788
805
}
789
806
807
+ // No checks in NoChecks
808
+ fn check_pk < Pk : MiniscriptKey > ( _pk : & Pk ) -> Result < ( ) , ScriptContextError > {
809
+ Ok ( ( ) )
810
+ }
811
+
790
812
fn check_global_policy_validity < Pk : MiniscriptKey > (
791
813
_ms : & Miniscript < Pk , Self > ,
792
814
) -> Result < ( ) , ScriptContextError > {
0 commit comments