@@ -28,6 +28,7 @@ use crate::{
28
28
// Hidden leaves are not yet supported in descriptor spec. Conceptually, it should
29
29
// be simple to integrate those here, but it is best to wait on core for the exact syntax.
30
30
#[ derive( Clone , Ord , PartialOrd , Eq , PartialEq , Hash ) ]
31
+ #[ non_exhaustive]
31
32
pub enum TapTree < Pk : MiniscriptKey , Ext : Extension = NoExt > {
32
33
/// A taproot tree structure
33
34
Tree ( Arc < TapTree < Pk , Ext > > , Arc < TapTree < Pk , Ext > > ) ,
@@ -37,6 +38,7 @@ pub enum TapTree<Pk: MiniscriptKey, Ext: Extension = NoExt> {
37
38
// are of Leafversion::default
38
39
Leaf ( Arc < Miniscript < Pk , Tap , Ext > > ) ,
39
40
/// A taproot leaf denoting a spending condition in terms of Simplicity
41
+ #[ cfg( feature = "simplicity" ) ]
40
42
SimplicityLeaf ( Arc < simplicity:: Policy < Pk > > ) ,
41
43
}
42
44
@@ -119,7 +121,9 @@ impl<Pk: MiniscriptKey, Ext: Extension> TapTree<Pk, Ext> {
119
121
TapTree :: Tree ( ref left_tree, ref right_tree) => {
120
122
1 + max ( left_tree. taptree_height ( ) , right_tree. taptree_height ( ) )
121
123
}
122
- TapTree :: Leaf ( ..) | TapTree :: SimplicityLeaf ( ..) => 0 ,
124
+ TapTree :: Leaf ( ..) => 0 ,
125
+ #[ cfg( feature = "simplicity" ) ]
126
+ TapTree :: SimplicityLeaf ( ..) => 0 ,
123
127
}
124
128
}
125
129
@@ -138,8 +142,10 @@ impl<Pk: MiniscriptKey, Ext: Extension> TapTree<Pk, Ext> {
138
142
Q : MiniscriptKey ,
139
143
Ext : Extension ,
140
144
{
145
+ #[ cfg( feature = "simplicity" ) ]
141
146
struct SimTranslator < ' a , T > ( & ' a mut T ) ;
142
147
148
+ #[ cfg( feature = "simplicity" ) ]
143
149
impl < ' a , Pk , T , Q , Error > simplicity:: Translator < Pk , Q , Error > for SimTranslator < ' a , T >
144
150
where
145
151
Pk : MiniscriptKey ,
@@ -161,6 +167,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> TapTree<Pk, Ext> {
161
167
Arc :: new ( r. translate_helper ( t) ?) ,
162
168
) ,
163
169
TapTree :: Leaf ( ms) => TapTree :: Leaf ( Arc :: new ( ms. translate_pk ( t) ?) ) ,
170
+ #[ cfg( feature = "simplicity" ) ]
164
171
TapTree :: SimplicityLeaf ( sim) => TapTree :: SimplicityLeaf ( Arc :: new ( sim. translate ( & mut SimTranslator ( t) ) ?) )
165
172
} ;
166
173
Ok ( frag)
@@ -179,6 +186,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> TapTree<Pk, Ext> {
179
186
Arc :: new ( r. translate_ext_helper ( t) ?) ,
180
187
) ,
181
188
TapTree :: Leaf ( ms) => TapTree :: Leaf ( Arc :: new ( ms. translate_ext ( t) ?) ) ,
189
+ #[ cfg( feature = "simplicity" ) ]
182
190
TapTree :: SimplicityLeaf ( sim) => TapTree :: SimplicityLeaf ( Arc :: clone ( sim) ) ,
183
191
} ;
184
192
Ok ( frag)
@@ -190,6 +198,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> fmt::Display for TapTree<Pk, Ext> {
190
198
match self {
191
199
TapTree :: Tree ( ref left, ref right) => write ! ( f, "{{{},{}}}" , * left, * right) ,
192
200
TapTree :: Leaf ( ref script) => write ! ( f, "{}" , * script) ,
201
+ #[ cfg( feature = "simplicity" ) ]
193
202
TapTree :: SimplicityLeaf ( ref policy) => write ! ( f, "sim{{{}}}" , policy) ,
194
203
}
195
204
}
@@ -200,6 +209,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> fmt::Debug for TapTree<Pk, Ext> {
200
209
match self {
201
210
TapTree :: Tree ( ref left, ref right) => write ! ( f, "{{{:?},{:?}}}" , * left, * right) ,
202
211
TapTree :: Leaf ( ref script) => write ! ( f, "{:?}" , * script) ,
212
+ #[ cfg( feature = "simplicity" ) ]
203
213
TapTree :: SimplicityLeaf ( ref policy) => write ! ( f, "{:?}" , policy) ,
204
214
}
205
215
}
@@ -288,6 +298,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> Tr<Pk, Ext> {
288
298
match script {
289
299
TapLeafScript :: Miniscript ( ms) => ms. sanity_check ( ) ?,
290
300
// TODO: Add sanity check for Simplicity policies
301
+ #[ cfg( feature = "simplicity" ) ]
291
302
TapLeafScript :: Simplicity ( ..) => { } ,
292
303
}
293
304
}
@@ -432,10 +443,12 @@ impl<Pk: MiniscriptKey + ToPublicKey, Ext: ParseableExt> Tr<Pk, Ext> {
432
443
433
444
/// Script at a tap leaf.
434
445
#[ derive( Copy , Clone , Debug , Ord , PartialOrd , Eq , PartialEq , Hash ) ]
446
+ #[ non_exhaustive]
435
447
pub enum TapLeafScript < ' a , Pk : MiniscriptKey , Ext : Extension > {
436
448
/// Miniscript leaf
437
449
Miniscript ( & ' a Miniscript < Pk , Tap , Ext > ) ,
438
450
/// Simplicity leaf
451
+ #[ cfg( feature = "simplicity" ) ]
439
452
Simplicity ( & ' a simplicity:: Policy < Pk > )
440
453
}
441
454
@@ -444,11 +457,13 @@ impl<'a, Pk: MiniscriptKey, Ext: Extension> TapLeafScript<'a, Pk, Ext> {
444
457
pub fn as_miniscript ( & self ) -> Option < & ' a Miniscript < Pk , Tap , Ext > > {
445
458
match self {
446
459
TapLeafScript :: Miniscript ( ms) => Some ( ms) ,
460
+ #[ cfg( feature = "simplicity" ) ]
447
461
_ => None ,
448
462
}
449
463
}
450
464
451
465
/// Get the Simplicity policy at the leaf, if it exists.
466
+ #[ cfg( feature = "simplicity" ) ]
452
467
pub fn as_simplicity ( & self ) -> Option < & ' a simplicity:: Policy < Pk > > {
453
468
match self {
454
469
TapLeafScript :: Simplicity ( sim) => Some ( sim) ,
@@ -460,6 +475,7 @@ impl<'a, Pk: MiniscriptKey, Ext: Extension> TapLeafScript<'a, Pk, Ext> {
460
475
pub fn version ( & self ) -> LeafVersion {
461
476
match self {
462
477
TapLeafScript :: Miniscript ( ..) => LeafVersion :: default ( ) ,
478
+ #[ cfg( feature = "simplicity" ) ]
463
479
TapLeafScript :: Simplicity ( ..) => simplicity:: leaf_version ( ) ,
464
480
}
465
481
}
@@ -469,6 +485,7 @@ impl<'a, Pk: MiniscriptKey, Ext: Extension> TapLeafScript<'a, Pk, Ext> {
469
485
match self {
470
486
TapLeafScript :: Miniscript ( ms) => ms. script_size ( ) ,
471
487
// Simplicity's witness script is always a 32-byte CMR
488
+ #[ cfg( feature = "simplicity" ) ]
472
489
TapLeafScript :: Simplicity ( ..) => 32 ,
473
490
}
474
491
}
@@ -482,6 +499,7 @@ impl<'a, Pk: MiniscriptKey, Ext: Extension> TapLeafScript<'a, Pk, Ext> {
482
499
// (1) Encoded program+witness
483
500
// (2) CMR program
484
501
// The third element is the control block, which is not counted by this method.
502
+ #[ cfg( feature = "simplicity" ) ]
485
503
TapLeafScript :: Simplicity ( ..) => Ok ( 2 ) ,
486
504
}
487
505
}
@@ -493,6 +511,7 @@ impl<'a, Pk: MiniscriptKey, Ext: Extension> TapLeafScript<'a, Pk, Ext> {
493
511
// There is currently no way to bound the Simplicity witness size without producing one
494
512
// We mark the witness size as malleable since it depends on the chosen spending path
495
513
// TODO: Add method to simplicity::Policy and use it here
514
+ #[ cfg( feature = "simplicity" ) ]
496
515
TapLeafScript :: Simplicity ( ..) => Err ( Error :: AnalysisError ( crate :: AnalysisError :: Malleable ) )
497
516
}
498
517
}
@@ -501,6 +520,7 @@ impl<'a, Pk: MiniscriptKey, Ext: Extension> TapLeafScript<'a, Pk, Ext> {
501
520
pub fn iter_pk ( & self ) -> Box < dyn Iterator < Item =Pk > + ' a > {
502
521
match self {
503
522
TapLeafScript :: Miniscript ( ms) => Box :: new ( ms. iter_pk ( ) ) ,
523
+ #[ cfg( feature = "simplicity" ) ]
504
524
TapLeafScript :: Simplicity ( sim) => Box :: new ( sim. iter_pk ( ) ) ,
505
525
}
506
526
}
@@ -511,6 +531,7 @@ impl<'a, Pk: ToPublicKey, Ext: ParseableExt> TapLeafScript<'a, Pk, Ext> {
511
531
pub fn encode ( & self ) -> Script {
512
532
match self {
513
533
TapLeafScript :: Miniscript ( ms) => ms. encode ( ) ,
534
+ #[ cfg( feature = "simplicity" ) ]
514
535
TapLeafScript :: Simplicity ( sim) => {
515
536
Script :: from ( sim. cmr ( ) . as_ref ( ) . to_vec ( ) )
516
537
}
@@ -522,6 +543,7 @@ impl<'a, Pk: ToPublicKey, Ext: ParseableExt> TapLeafScript<'a, Pk, Ext> {
522
543
match self {
523
544
TapLeafScript :: Miniscript ( ms) => ms. satisfy_malleable ( satisfier) ,
524
545
// There doesn't (yet?) exist a malleable satisfaction of Simplicity policy
546
+ #[ cfg( feature = "simplicity" ) ]
525
547
TapLeafScript :: Simplicity ( ..) => self . satisfy ( satisfier) ,
526
548
}
527
549
}
@@ -530,6 +552,7 @@ impl<'a, Pk: ToPublicKey, Ext: ParseableExt> TapLeafScript<'a, Pk, Ext> {
530
552
pub fn satisfy < S : Satisfier < Pk > > ( & self , satisfier : S ) -> Result < Vec < Vec < u8 > > , Error > {
531
553
match self {
532
554
TapLeafScript :: Miniscript ( ms) => ms. satisfy ( satisfier) ,
555
+ #[ cfg( feature = "simplicity" ) ]
533
556
TapLeafScript :: Simplicity ( sim) => {
534
557
let satisfier = crate :: simplicity:: SatisfierWrapper :: new ( satisfier) ;
535
558
let program = sim. satisfy ( & satisfier) . map_err ( |_| Error :: CouldNotSatisfy ) ?;
@@ -577,6 +600,7 @@ where
577
600
TapTree :: Leaf ( ref ms) => {
578
601
return Some ( ( depth, TapLeafScript :: Miniscript ( ms) ) )
579
602
} ,
603
+ #[ cfg( feature = "simplicity" ) ]
580
604
TapTree :: SimplicityLeaf ( ref sim) => {
581
605
return Some ( ( depth, TapLeafScript :: Simplicity ( sim) ) )
582
606
}
@@ -593,6 +617,7 @@ impl_block_str!(
593
617
// Helper function to parse taproot script path
594
618
fn parse_tr_script_spend( tree: & expression:: Tree , ) -> Result <TapTree <Pk , Ext >, Error > {
595
619
match tree {
620
+ #[ cfg( feature = "simplicity" ) ]
596
621
expression:: Tree { name, args } if * name == "sim" && args. len( ) == 1 => {
597
622
let policy = crate :: simplicity:: PolicyWrapper :: <Pk >:: from_str( args[ 0 ] . name) ?;
598
623
Ok ( TapTree :: SimplicityLeaf ( Arc :: new( policy. 0 ) ) )
@@ -771,6 +796,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> Liftable<Pk> for TapTree<Pk, Ext> {
771
796
Ok ( Policy :: Threshold ( 1 , vec ! [ lift_helper( l) ?, lift_helper( r) ?] ) )
772
797
}
773
798
TapTree :: Leaf ( ref leaf) => leaf. lift ( ) ,
799
+ #[ cfg( feature = "simplicity" ) ]
774
800
TapTree :: SimplicityLeaf ( ..) => panic ! ( "FIXME: Cannot lift Simplicity policy to Miniscript semantic policy" ) ,
775
801
}
776
802
}
@@ -802,6 +828,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> ForEachKey<Pk> for Tr<Pk, Ext> {
802
828
. all ( |( _d, script) | {
803
829
match script {
804
830
TapLeafScript :: Miniscript ( ms) => ms. for_each_key ( & mut pred) ,
831
+ #[ cfg( feature = "simplicity" ) ]
805
832
TapLeafScript :: Simplicity ( sim) => crate :: simplicity:: for_each_key ( sim, & mut pred) ,
806
833
}
807
834
} ) ;
@@ -976,17 +1003,20 @@ mod tests {
976
1003
& [ TapLeafScript :: Miniscript ( & ms) ]
977
1004
) ;
978
1005
979
- // Simplicity key spend
980
- let sim = simplicity:: Policy :: Key ( "a" . to_string ( ) ) ;
981
- verify_from_str (
982
- "eltr(internal,sim{pk(a)})#duhmnzmm" , "internal" ,
983
- & [ TapLeafScript :: Simplicity ( & sim) ]
984
- ) ;
985
-
986
- // Mixed Miniscript and Simplicity
987
- verify_from_str (
988
- "eltr(internal,{pk(a),sim{pk(a)}})#7vmfhpaj" , "internal" ,
989
- & [ TapLeafScript :: Miniscript ( & ms) , TapLeafScript :: Simplicity ( & sim) ]
990
- ) ;
1006
+ #[ cfg( feature = "simplicity" ) ]
1007
+ {
1008
+ // Simplicity key spend
1009
+ let sim = simplicity:: Policy :: Key ( "a" . to_string ( ) ) ;
1010
+ verify_from_str (
1011
+ "eltr(internal,sim{pk(a)})#duhmnzmm" , "internal" ,
1012
+ & [ TapLeafScript :: Simplicity ( & sim) ]
1013
+ ) ;
1014
+
1015
+ // Mixed Miniscript and Simplicity
1016
+ verify_from_str (
1017
+ "eltr(internal,{pk(a),sim{pk(a)}})#7vmfhpaj" , "internal" ,
1018
+ & [ TapLeafScript :: Miniscript ( & ms) , TapLeafScript :: Simplicity ( & sim) ]
1019
+ ) ;
1020
+ }
991
1021
}
992
1022
}
0 commit comments