@@ -36,6 +36,8 @@ pub enum TapTree<Pk: MiniscriptKey, Ext: Extension = NoExt> {
36
36
// in adding a LeafVersion with Leaf type here. All Miniscripts right now
37
37
// are of Leafversion::default
38
38
Leaf ( Arc < Miniscript < Pk , Tap , Ext > > ) ,
39
+ /// A taproot leaf denoting a spending condition in terms of Simplicity
40
+ SimplicityLeaf ( Arc < simplicity:: Policy < Pk > > ) ,
39
41
}
40
42
41
43
/// A taproot descriptor
@@ -117,7 +119,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> TapTree<Pk, Ext> {
117
119
TapTree :: Tree ( ref left_tree, ref right_tree) => {
118
120
1 + max ( left_tree. taptree_height ( ) , right_tree. taptree_height ( ) )
119
121
}
120
- TapTree :: Leaf ( ..) => 0 ,
122
+ TapTree :: Leaf ( ..) | TapTree :: SimplicityLeaf ( .. ) => 0 ,
121
123
}
122
124
}
123
125
@@ -136,12 +138,30 @@ impl<Pk: MiniscriptKey, Ext: Extension> TapTree<Pk, Ext> {
136
138
Q : MiniscriptKey ,
137
139
Ext : Extension ,
138
140
{
141
+ struct SimTranslator < ' a , T > ( & ' a mut T ) ;
142
+
143
+ impl < ' a , Pk , T , Q , Error > simplicity:: Translator < Pk , Q , Error > for SimTranslator < ' a , T >
144
+ where
145
+ Pk : MiniscriptKey ,
146
+ T : Translator < Pk , Q , Error > ,
147
+ Q : MiniscriptKey ,
148
+ {
149
+ fn pk ( & mut self , pk : & Pk ) -> Result < Q , Error > {
150
+ self . 0 . pk ( pk)
151
+ }
152
+
153
+ fn sha256 ( & mut self , sha256 : & Pk :: Sha256 ) -> Result < Q :: Sha256 , Error > {
154
+ self . 0 . sha256 ( sha256)
155
+ }
156
+ }
157
+
139
158
let frag = match self {
140
159
TapTree :: Tree ( l, r) => TapTree :: Tree (
141
160
Arc :: new ( l. translate_helper ( t) ?) ,
142
161
Arc :: new ( r. translate_helper ( t) ?) ,
143
162
) ,
144
163
TapTree :: Leaf ( ms) => TapTree :: Leaf ( Arc :: new ( ms. translate_pk ( t) ?) ) ,
164
+ TapTree :: SimplicityLeaf ( sim) => TapTree :: SimplicityLeaf ( Arc :: new ( sim. translate ( & mut SimTranslator ( t) ) ?) )
145
165
} ;
146
166
Ok ( frag)
147
167
}
@@ -159,6 +179,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> TapTree<Pk, Ext> {
159
179
Arc :: new ( r. translate_ext_helper ( t) ?) ,
160
180
) ,
161
181
TapTree :: Leaf ( ms) => TapTree :: Leaf ( Arc :: new ( ms. translate_ext ( t) ?) ) ,
182
+ TapTree :: SimplicityLeaf ( sim) => TapTree :: SimplicityLeaf ( Arc :: clone ( sim) ) ,
162
183
} ;
163
184
Ok ( frag)
164
185
}
@@ -169,6 +190,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> fmt::Display for TapTree<Pk, Ext> {
169
190
match self {
170
191
TapTree :: Tree ( ref left, ref right) => write ! ( f, "{{{},{}}}" , * left, * right) ,
171
192
TapTree :: Leaf ( ref script) => write ! ( f, "{}" , * script) ,
193
+ TapTree :: SimplicityLeaf ( ref policy) => write ! ( f, "{}" , policy) ,
172
194
}
173
195
}
174
196
}
@@ -178,6 +200,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> fmt::Debug for TapTree<Pk, Ext> {
178
200
match self {
179
201
TapTree :: Tree ( ref left, ref right) => write ! ( f, "{{{:?},{:?}}}" , * left, * right) ,
180
202
TapTree :: Leaf ( ref script) => write ! ( f, "{:?}" , * script) ,
203
+ TapTree :: SimplicityLeaf ( ref policy) => write ! ( f, "{:?}" , policy) ,
181
204
}
182
205
}
183
206
}
@@ -244,7 +267,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> Tr<Pk, Ext> {
244
267
} else {
245
268
let mut builder = TaprootBuilder :: new ( ) ;
246
269
for ( depth, ms) in self . iter_scripts ( ) {
247
- let script = ms. encode ( ) ;
270
+ let script = ms. as_miniscript ( ) . unwrap ( ) . encode ( ) ;
248
271
builder = builder
249
272
. add_leaf ( depth, script)
250
273
. expect ( "Computing spend data on a valid Tree should always succeed" ) ;
@@ -263,7 +286,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> Tr<Pk, Ext> {
263
286
/// Checks whether the descriptor is safe.
264
287
pub fn sanity_check ( & self ) -> Result < ( ) , Error > {
265
288
for ( _depth, ms) in self . iter_scripts ( ) {
266
- ms. sanity_check ( ) ?;
289
+ ms. as_miniscript ( ) . unwrap ( ) . sanity_check ( ) ?;
267
290
}
268
291
Ok ( ( ) )
269
292
}
@@ -293,6 +316,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> Tr<Pk, Ext> {
293
316
294
317
tree. iter ( )
295
318
. filter_map ( |( depth, ms) | {
319
+ let ms = ms. as_miniscript ( ) . unwrap ( ) ;
296
320
let script_size = ms. script_size ( ) ;
297
321
let max_sat_elems = ms. max_satisfaction_witness_elements ( ) . ok ( ) ?;
298
322
let max_sat_size = ms. max_satisfaction_size ( ) . ok ( ) ?;
@@ -338,6 +362,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> Tr<Pk, Ext> {
338
362
339
363
tree. iter ( )
340
364
. filter_map ( |( depth, ms) | {
365
+ let ms = ms. as_miniscript ( ) . unwrap ( ) ;
341
366
let script_size = ms. script_size ( ) ;
342
367
let max_sat_elems = ms. max_satisfaction_witness_elements ( ) . ok ( ) ?;
343
368
let max_sat_size = ms. max_satisfaction_size ( ) . ok ( ) ?;
@@ -404,8 +429,38 @@ impl<Pk: MiniscriptKey + ToPublicKey, Ext: ParseableExt> Tr<Pk, Ext> {
404
429
}
405
430
}
406
431
407
- /// Iterator for Taproot structures
408
- /// Yields a pair of (depth, miniscript) in a depth first walk
432
+ /// Script at a tap leaf.
433
+ #[ derive( Copy , Clone , Debug , Ord , PartialOrd , Eq , PartialEq , Hash ) ]
434
+ pub enum TapLeafScript < ' a , Pk : MiniscriptKey , Ext : Extension > {
435
+ /// Miniscript leaf
436
+ Miniscript ( & ' a Miniscript < Pk , Tap , Ext > ) ,
437
+ /// Simplicity leaf
438
+ Simplicity ( & ' a simplicity:: Policy < Pk > )
439
+ }
440
+
441
+ impl < ' a , Pk : MiniscriptKey , Ext : Extension > TapLeafScript < ' a , Pk , Ext > {
442
+ /// Get the Miniscript at the leaf, if it exists.
443
+ pub fn as_miniscript ( & self ) -> Option < & ' a Miniscript < Pk , Tap , Ext > > {
444
+ match self {
445
+ TapLeafScript :: Miniscript ( ms) => Some ( ms) ,
446
+ _ => None ,
447
+ }
448
+ }
449
+
450
+ /// Get the Simplicity policy at the leaf, if it exists.
451
+ pub fn as_simplicity ( & self ) -> Option < & ' a simplicity:: Policy < Pk > > {
452
+ match self {
453
+ TapLeafScript :: Simplicity ( sim) => Some ( sim) ,
454
+ _ => None ,
455
+ }
456
+ }
457
+ }
458
+
459
+ /// Iterator over the leaves of a tap tree.
460
+ ///
461
+ /// Each leaf consists is a pair of (depth, script).
462
+ /// The leaves are yielded in a depth-first walk.
463
+ ///
409
464
/// For example, this tree:
410
465
/// - N0 -
411
466
/// / \\
@@ -426,7 +481,7 @@ where
426
481
Pk : MiniscriptKey + ' a ,
427
482
Ext : Extension ,
428
483
{
429
- type Item = ( usize , & ' a Miniscript < Pk , Tap , Ext > ) ;
484
+ type Item = ( usize , TapLeafScript < ' a , Pk , Ext > ) ;
430
485
431
486
fn next ( & mut self ) -> Option < Self :: Item > {
432
487
while let Some ( ( depth, last) ) = self . stack . pop ( ) {
@@ -435,7 +490,12 @@ where
435
490
self . stack . push ( ( depth + 1 , r) ) ;
436
491
self . stack . push ( ( depth + 1 , l) ) ;
437
492
}
438
- TapTree :: Leaf ( ref ms) => return Some ( ( depth, ms) ) ,
493
+ TapTree :: Leaf ( ref ms) => {
494
+ return Some ( ( depth, TapLeafScript :: Miniscript ( ms) ) )
495
+ } ,
496
+ TapTree :: SimplicityLeaf ( ref sim) => {
497
+ return Some ( ( depth, TapLeafScript :: Simplicity ( sim) ) )
498
+ }
439
499
}
440
500
}
441
501
None
@@ -623,6 +683,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> Liftable<Pk> for TapTree<Pk, Ext> {
623
683
Ok ( Policy :: Threshold ( 1 , vec ! [ lift_helper( l) ?, lift_helper( r) ?] ) )
624
684
}
625
685
TapTree :: Leaf ( ref leaf) => leaf. lift ( ) ,
686
+ TapTree :: SimplicityLeaf ( ..) => panic ! ( "Cannot lift Simplicity policy to Miniscript semantic policy" ) ,
626
687
}
627
688
}
628
689
@@ -650,7 +711,7 @@ impl<Pk: MiniscriptKey, Ext: Extension> ForEachKey<Pk> for Tr<Pk, Ext> {
650
711
{
651
712
let script_keys_res = self
652
713
. iter_scripts ( )
653
- . all ( |( _d, ms) | ms. for_each_key ( & mut pred) ) ;
714
+ . all ( |( _d, ms) | ms. as_miniscript ( ) . unwrap ( ) . for_each_key ( & mut pred) ) ;
654
715
script_keys_res && pred ( & self . internal_key )
655
716
}
656
717
}
@@ -729,6 +790,7 @@ where
729
790
// map (lookup_control_block) from the satisfier here.
730
791
let ( mut min_wit, mut min_wit_len) = ( None , None ) ;
731
792
for ( depth, ms) in desc. iter_scripts ( ) {
793
+ let ms = ms. as_miniscript ( ) . unwrap ( ) ;
732
794
let mut wit = if allow_mall {
733
795
match ms. satisfy_malleable ( & satisfier) {
734
796
Ok ( wit) => wit,
0 commit comments