14
14
15
15
use std:: { fmt, hash} ;
16
16
17
+ use bitcoin;
17
18
use bitcoin:: blockdata:: constants:: MAX_BLOCK_WEIGHT ;
18
19
use miniscript:: limits:: {
19
20
MAX_OPS_PER_SCRIPT , MAX_SCRIPTSIG_SIZE , MAX_SCRIPT_ELEMENT_SIZE , MAX_SCRIPT_SIZE ,
@@ -23,6 +24,8 @@ use miniscript::types;
23
24
use util:: witness_to_scriptsig;
24
25
use Error ;
25
26
27
+ use super :: decode:: ParseableKey ;
28
+
26
29
use { Miniscript , MiniscriptKey , Terminal } ;
27
30
28
31
/// Error for Script Context
@@ -129,7 +132,11 @@ impl fmt::Display for ScriptContextError {
129
132
/// For example, disallowing uncompressed keys in Segwit context
130
133
pub trait ScriptContext :
131
134
fmt:: Debug + Clone + Ord + PartialOrd + Eq + PartialEq + hash:: Hash + private:: Sealed
135
+ where
136
+ Self :: Key : MiniscriptKey < Hash = bitcoin:: hashes:: hash160:: Hash > ,
132
137
{
138
+ /// The consensus key associated with the type. Must be a parseable key
139
+ type Key : ParseableKey ;
133
140
/// Depending on ScriptContext, fragments can be malleable. For Example,
134
141
/// under Legacy context, PkH is malleable because it is possible to
135
142
/// estimate the cost of satisfaction because of compressed keys
@@ -276,6 +283,9 @@ pub trait ScriptContext:
276
283
/// 34/66 for Bare/Legacy based on key compressedness
277
284
/// 34 for Segwitv0, 33 for Tap
278
285
fn pk_len < Pk : MiniscriptKey > ( pk : & Pk ) -> usize ;
286
+
287
+ /// Local helper function to display error messages with context
288
+ fn to_str ( ) -> & ' static str ;
279
289
}
280
290
281
291
/// Legacy ScriptContext
@@ -286,6 +296,7 @@ pub trait ScriptContext:
286
296
pub enum Legacy { }
287
297
288
298
impl ScriptContext for Legacy {
299
+ type Key = bitcoin:: PublicKey ;
289
300
fn check_terminal_non_malleable < Pk : MiniscriptKey , Ctx : ScriptContext > (
290
301
frag : & Terminal < Pk , Ctx > ,
291
302
) -> Result < ( ) , ScriptContextError > {
@@ -358,13 +369,18 @@ impl ScriptContext for Legacy {
358
369
34
359
370
}
360
371
}
372
+
373
+ fn to_str ( ) -> & ' static str {
374
+ "Legacy/p2sh"
375
+ }
361
376
}
362
377
363
378
/// Segwitv0 ScriptContext
364
379
#[ derive( Debug , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
365
380
pub enum Segwitv0 { }
366
381
367
382
impl ScriptContext for Segwitv0 {
383
+ type Key = bitcoin:: PublicKey ;
368
384
fn check_terminal_non_malleable < Pk : MiniscriptKey , Ctx : ScriptContext > (
369
385
_frag : & Terminal < Pk , Ctx > ,
370
386
) -> Result < ( ) , ScriptContextError > {
@@ -451,13 +467,18 @@ impl ScriptContext for Segwitv0 {
451
467
fn pk_len < Pk : MiniscriptKey > ( _pk : & Pk ) -> usize {
452
468
34
453
469
}
470
+
471
+ fn to_str ( ) -> & ' static str {
472
+ "Segwitv0"
473
+ }
454
474
}
455
475
456
476
/// Tap ScriptContext
457
477
#[ derive( Debug , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
458
478
pub enum Tap { }
459
479
460
480
impl ScriptContext for Tap {
481
+ type Key = bitcoin:: schnorr:: PublicKey ;
461
482
fn check_terminal_non_malleable < Pk : MiniscriptKey , Ctx : ScriptContext > (
462
483
_frag : & Terminal < Pk , Ctx > ,
463
484
) -> Result < ( ) , ScriptContextError > {
@@ -546,6 +567,10 @@ impl ScriptContext for Tap {
546
567
fn pk_len < Pk : MiniscriptKey > ( _pk : & Pk ) -> usize {
547
568
33
548
569
}
570
+
571
+ fn to_str ( ) -> & ' static str {
572
+ "TapscriptCtx"
573
+ }
549
574
}
550
575
551
576
/// Bare ScriptContext
@@ -556,6 +581,7 @@ impl ScriptContext for Tap {
556
581
pub enum BareCtx { }
557
582
558
583
impl ScriptContext for BareCtx {
584
+ type Key = bitcoin:: PublicKey ;
559
585
fn check_terminal_non_malleable < Pk : MiniscriptKey , Ctx : ScriptContext > (
560
586
_frag : & Terminal < Pk , Ctx > ,
561
587
) -> Result < ( ) , ScriptContextError > {
@@ -615,6 +641,10 @@ impl ScriptContext for BareCtx {
615
641
33
616
642
}
617
643
}
644
+
645
+ fn to_str ( ) -> & ' static str {
646
+ "BareCtx"
647
+ }
618
648
}
619
649
620
650
/// "No Checks" Context
@@ -625,6 +655,8 @@ impl ScriptContext for BareCtx {
625
655
#[ derive( Debug , Clone , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
626
656
pub enum NoChecks { }
627
657
impl ScriptContext for NoChecks {
658
+ // todo: When adding support for interpreter, we need a enum with all supported keys here
659
+ type Key = bitcoin:: PublicKey ;
628
660
fn check_terminal_non_malleable < Pk : MiniscriptKey , Ctx : ScriptContext > (
629
661
_frag : & Terminal < Pk , Ctx > ,
630
662
) -> Result < ( ) , ScriptContextError > {
@@ -664,6 +696,11 @@ impl ScriptContext for NoChecks {
664
696
fn pk_len < Pk : MiniscriptKey > ( _pk : & Pk ) -> usize {
665
697
panic ! ( "Tried to compute a pk len bound on a no-checks miniscript" )
666
698
}
699
+
700
+ fn to_str ( ) -> & ' static str {
701
+ // Internally used code
702
+ "NochecksCtx"
703
+ }
667
704
}
668
705
669
706
/// Private Mod to prevent downstream from implementing this public trait
0 commit comments