@@ -45,6 +45,9 @@ pub enum ScriptContextError {
45
45
/// Only Compressed keys allowed under current descriptor
46
46
/// Segwitv0 fragments do not allow uncompressed pubkeys
47
47
CompressedOnly ( String ) ,
48
+ /// XOnly keys are only allowed in Tap context
49
+ /// The first element is key, and second element is current script context
50
+ XOnlyKeysNotAllowed ( String , & ' static str ) ,
48
51
/// Tapscript descriptors cannot contain uncompressed keys
49
52
/// Tap context can contain compressed or xonly
50
53
UncompressedKeysNotAllowed ,
@@ -97,6 +100,9 @@ impl fmt::Display for ScriptContextError {
97
100
pk
98
101
)
99
102
}
103
+ ScriptContextError :: XOnlyKeysNotAllowed ( ref pk, ref ctx) => {
104
+ write ! ( f, "x-only key {} not allowed in {}" , pk, ctx)
105
+ }
100
106
ScriptContextError :: UncompressedKeysNotAllowed => {
101
107
write ! (
102
108
f,
@@ -345,10 +351,24 @@ impl ScriptContext for Legacy {
345
351
}
346
352
347
353
match ms. node {
354
+ Terminal :: PkK ( ref key) if key. is_x_only_key ( ) => {
355
+ return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
356
+ key. to_string ( ) ,
357
+ Self :: name_str ( ) ,
358
+ ) )
359
+ }
348
360
Terminal :: Multi ( _k, ref pks) => {
349
361
if pks. len ( ) > MAX_PUBKEYS_PER_MULTISIG {
350
362
return Err ( ScriptContextError :: CheckMultiSigLimitExceeded ) ;
351
363
}
364
+ for pk in pks. iter ( ) {
365
+ if pk. is_x_only_key ( ) {
366
+ return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
367
+ pk. to_string ( ) ,
368
+ Self :: name_str ( ) ,
369
+ ) ) ;
370
+ }
371
+ }
352
372
}
353
373
Terminal :: MultiA ( ..) => {
354
374
return Err ( ScriptContextError :: MultiANotAllowed ) ;
@@ -440,6 +460,11 @@ impl ScriptContext for Segwitv0 {
440
460
Terminal :: PkK ( ref pk) => {
441
461
if pk. is_uncompressed ( ) {
442
462
return Err ( ScriptContextError :: CompressedOnly ( pk. to_string ( ) ) ) ;
463
+ } else if pk. is_x_only_key ( ) {
464
+ return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
465
+ pk. to_string ( ) ,
466
+ Self :: name_str ( ) ,
467
+ ) ) ;
443
468
}
444
469
Ok ( ( ) )
445
470
}
@@ -450,6 +475,11 @@ impl ScriptContext for Segwitv0 {
450
475
for pk in pks. iter ( ) {
451
476
if pk. is_uncompressed ( ) {
452
477
return Err ( ScriptContextError :: CompressedOnly ( pk. to_string ( ) ) ) ;
478
+ } else if pk. is_x_only_key ( ) {
479
+ return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
480
+ pk. to_string ( ) ,
481
+ Self :: name_str ( ) ,
482
+ ) ) ;
453
483
}
454
484
}
455
485
Ok ( ( ) )
@@ -652,10 +682,30 @@ impl ScriptContext for BareCtx {
652
682
if ms. ext . pk_cost > MAX_SCRIPT_SIZE {
653
683
return Err ( ScriptContextError :: MaxWitnessScriptSizeExceeded ) ;
654
684
}
655
- if let Terminal :: MultiA ( ..) = ms. node {
656
- return Err ( ScriptContextError :: MultiANotAllowed ) ;
685
+ match ms. node {
686
+ Terminal :: PkK ( ref key) if key. is_x_only_key ( ) => {
687
+ return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
688
+ key. to_string ( ) ,
689
+ Self :: name_str ( ) ,
690
+ ) )
691
+ }
692
+ Terminal :: Multi ( _k, ref pks) => {
693
+ if pks. len ( ) > MAX_PUBKEYS_PER_MULTISIG {
694
+ return Err ( ScriptContextError :: CheckMultiSigLimitExceeded ) ;
695
+ }
696
+ for pk in pks. iter ( ) {
697
+ if pk. is_x_only_key ( ) {
698
+ return Err ( ScriptContextError :: XOnlyKeysNotAllowed (
699
+ pk. to_string ( ) ,
700
+ Self :: name_str ( ) ,
701
+ ) ) ;
702
+ }
703
+ }
704
+ Ok ( ( ) )
705
+ }
706
+ Terminal :: MultiA ( ..) => return Err ( ScriptContextError :: MultiANotAllowed ) ,
707
+ _ => Ok ( ( ) ) ,
657
708
}
658
- Ok ( ( ) )
659
709
}
660
710
661
711
fn check_local_consensus_validity < Pk : MiniscriptKey > (
0 commit comments