15
15
use bitcoin:: hashes:: { hash160, ripemd160, sha256, sha256d, Hash } ;
16
16
use bitcoin:: { self , secp256k1} ;
17
17
use fmt;
18
+ use miniscript:: { Any , Legacy , ScriptContext , Segwitv0 } ;
18
19
use Descriptor ;
19
20
use Terminal ;
20
21
use { error, Miniscript } ;
@@ -200,9 +201,9 @@ pub enum SatisfiedConstraint<'desc, 'stack> {
200
201
///the top of the stack, we need to decide whether to execute right child or not.
201
202
///This is also useful for wrappers and thresholds which push a value on the stack
202
203
///depending on evaluation of the children.
203
- struct NodeEvaluationState < ' desc > {
204
+ struct NodeEvaluationState < ' desc , Ctx : ScriptContext > {
204
205
///The node which is being evaluated
205
- node : & ' desc Miniscript < bitcoin:: PublicKey > ,
206
+ node : & ' desc Miniscript < bitcoin:: PublicKey , Ctx > ,
206
207
///number of children evaluated
207
208
n_evaluated : usize ,
208
209
///number of children satisfied
@@ -217,24 +218,35 @@ struct NodeEvaluationState<'desc> {
217
218
/// In case the script would abort on the given witness stack OR if the entire
218
219
/// script is dissatisfied, this would return keep on returning values
219
220
///_until_Error.
220
- pub struct SatisfiedConstraints < ' desc , ' stack , F : FnMut ( & bitcoin:: PublicKey , BitcoinSig ) -> bool > {
221
+ pub struct SatisfiedConstraintsIter <
222
+ ' desc ,
223
+ ' stack ,
224
+ Ctx : ScriptContext ,
225
+ F : FnMut ( & bitcoin:: PublicKey , BitcoinSig ) -> bool ,
226
+ > {
221
227
verify_sig : F ,
222
228
public_key : Option < & ' desc bitcoin:: PublicKey > ,
223
- state : Vec < NodeEvaluationState < ' desc > > ,
229
+ state : Vec < NodeEvaluationState < ' desc , Ctx > > ,
224
230
stack : Stack < ' stack > ,
225
231
age : u32 ,
226
232
height : u32 ,
227
233
has_errored : bool ,
228
234
}
229
235
236
+ pub enum SatisfiedConstraints < ' desc , ' stack , F : FnMut ( & bitcoin:: PublicKey , BitcoinSig ) -> bool > {
237
+ Legacy ( SatisfiedConstraintsIter < ' desc , ' stack , Legacy , F > ) ,
238
+ Segwitv0 ( SatisfiedConstraintsIter < ' desc , ' stack , Segwitv0 , F > ) ,
239
+ Any ( SatisfiedConstraintsIter < ' desc , ' stack , Any , F > ) ,
240
+ }
230
241
/// Stack Data structure representing the stack input to Miniscript. This Stack
231
242
/// is created from the combination of ScriptSig and Witness stack.
232
243
#[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Debug , Hash ) ]
233
244
pub struct Stack < ' stack > ( pub Vec < StackElement < ' stack > > ) ;
234
245
235
- ///Iterator for SatisfiedConstraints
236
- impl < ' desc , ' stack , F > Iterator for SatisfiedConstraints < ' desc , ' stack , F >
246
+ ///Iterator for SatisfiedConstraintsIter
247
+ impl < ' desc , ' stack , Ctx , F > Iterator for SatisfiedConstraintsIter < ' desc , ' stack , Ctx , F >
237
248
where
249
+ Ctx : ScriptContext ,
238
250
F : FnMut ( & bitcoin:: PublicKey , BitcoinSig ) -> bool ,
239
251
{
240
252
type Item = Result < SatisfiedConstraint < ' desc , ' stack > , Error > ;
@@ -257,36 +269,21 @@ impl<'desc, 'stack, F> SatisfiedConstraints<'desc, 'stack, F>
257
269
where
258
270
F : FnMut ( & bitcoin:: PublicKey , BitcoinSig ) -> bool ,
259
271
{
260
- /// Helper function to push a NodeEvaluationState on state stack
261
- fn push_evaluation_state (
262
- & mut self ,
263
- node : & ' desc Miniscript < bitcoin:: PublicKey > ,
264
- n_evaluated : usize ,
265
- n_satisfied : usize ,
266
- ) -> ( ) {
267
- self . state . push ( NodeEvaluationState {
268
- node,
269
- n_evaluated,
270
- n_satisfied,
271
- } )
272
- }
273
-
274
- /// Creates a new iterator over all constraints satisfied for a given
272
+ // Creates a new iterator over all constraints satisfied for a given
275
273
/// descriptor by a given witness stack. Because this iterator is lazy,
276
274
/// it may return satisfied constraints even if these turn out to be
277
275
/// irrelevant to the final (dis)satisfaction of the descriptor.
276
+ /// Because the iterator is dependent evaluating the miniscript, it is
277
+ /// dependent on scriptContext
278
278
pub fn from_descriptor (
279
279
des : & ' desc Descriptor < bitcoin:: PublicKey > ,
280
280
stack : Stack < ' stack > ,
281
281
verify_sig : F ,
282
282
age : u32 ,
283
283
height : u32 ,
284
- ) -> SatisfiedConstraints < ' desc , ' stack , F > {
284
+ ) -> SatisfiedConstraintsIter < ' desc , ' stack , Any , F > {
285
285
match des {
286
- & Descriptor :: Pk ( ref pk)
287
- | & Descriptor :: Pkh ( ref pk)
288
- | & Descriptor :: ShWpkh ( ref pk)
289
- | & Descriptor :: Wpkh ( ref pk) => SatisfiedConstraints {
286
+ & Descriptor :: Pk ( ref pk) | & Descriptor :: Pkh ( ref pk) => SatisfiedConstraintsIter {
290
287
verify_sig : verify_sig,
291
288
public_key : Some ( pk) ,
292
289
state : vec ! [ ] ,
@@ -295,24 +292,67 @@ where
295
292
height,
296
293
has_errored : false ,
297
294
} ,
298
- & Descriptor :: Sh ( ref miniscript)
299
- | & Descriptor :: Bare ( ref miniscript)
300
- | & Descriptor :: ShWsh ( ref miniscript)
301
- | & Descriptor :: Wsh ( ref miniscript) => SatisfiedConstraints {
295
+ & Descriptor :: ShWpkh ( ref pk) | & Descriptor :: Wpkh ( ref pk) => SatisfiedConstraintsIter {
302
296
verify_sig : verify_sig,
303
- public_key : None ,
304
- state : vec ! [ NodeEvaluationState {
305
- node: miniscript,
306
- n_evaluated: 0 ,
307
- n_satisfied: 0 ,
308
- } ] ,
297
+ public_key : Some ( pk) ,
298
+ state : vec ! [ ] ,
309
299
stack : stack,
310
300
age,
311
301
height,
312
302
has_errored : false ,
313
303
} ,
304
+ & Descriptor :: Wsh ( ref miniscript) | & Descriptor :: ShWsh ( ref miniscript) => {
305
+ SatisfiedConstraintsIter {
306
+ verify_sig : verify_sig,
307
+ public_key : None ,
308
+ state : vec ! [ NodeEvaluationState {
309
+ node: Any :: from_segwitv0( miniscript) ,
310
+ n_evaluated: 0 ,
311
+ n_satisfied: 0 ,
312
+ } ] ,
313
+ stack : stack,
314
+ age,
315
+ height,
316
+ has_errored : false ,
317
+ }
318
+ }
319
+ & Descriptor :: Sh ( ref miniscript) | & Descriptor :: Bare ( ref miniscript) => {
320
+ SatisfiedConstraintsIter {
321
+ verify_sig : verify_sig,
322
+ public_key : None ,
323
+ state : vec ! [ NodeEvaluationState {
324
+ node: Any :: from_legacy( miniscript) ,
325
+ n_evaluated: 0 ,
326
+ n_satisfied: 0 ,
327
+ } ] ,
328
+ stack : stack,
329
+ age,
330
+ height,
331
+ has_errored : false ,
332
+ }
333
+ }
314
334
}
315
335
}
336
+ }
337
+
338
+ impl < ' desc , ' stack , Ctx , F > SatisfiedConstraintsIter < ' desc , ' stack , Ctx , F >
339
+ where
340
+ Ctx : ScriptContext ,
341
+ F : FnMut ( & bitcoin:: PublicKey , BitcoinSig ) -> bool ,
342
+ {
343
+ /// Helper function to push a NodeEvaluationState on state stack
344
+ fn push_evaluation_state (
345
+ & mut self ,
346
+ node : & ' desc Miniscript < bitcoin:: PublicKey , Ctx > ,
347
+ n_evaluated : usize ,
348
+ n_satisfied : usize ,
349
+ ) -> ( ) {
350
+ self . state . push ( NodeEvaluationState {
351
+ node,
352
+ n_evaluated,
353
+ n_satisfied,
354
+ } )
355
+ }
316
356
317
357
/// Helper function to step the iterator
318
358
fn iter_next ( & mut self ) -> Option < Result < SatisfiedConstraint < ' desc , ' stack > , Error > > {
@@ -1019,9 +1059,10 @@ mod tests {
1019
1059
use bitcoin:: hashes:: { hash160, ripemd160, sha256, sha256d, Hash } ;
1020
1060
use bitcoin:: secp256k1:: { self , Secp256k1 , VerifyOnly } ;
1021
1061
use descriptor:: satisfied_constraints:: {
1022
- Error , HashLockType , NodeEvaluationState , SatisfiedConstraint , SatisfiedConstraints , Stack ,
1023
- StackElement ,
1062
+ Error , HashLockType , NodeEvaluationState , SatisfiedConstraint , SatisfiedConstraintsIter ,
1063
+ Stack , StackElement ,
1024
1064
} ;
1065
+ use miniscript:: Legacy ;
1025
1066
use std:: str:: FromStr ;
1026
1067
use BitcoinSig ;
1027
1068
use Miniscript ;
@@ -1074,12 +1115,12 @@ mod tests {
1074
1115
fn from_stack < ' stack , ' elem , F > (
1075
1116
verify_fn : F ,
1076
1117
stack : Stack < ' stack > ,
1077
- ms : & ' elem Miniscript < bitcoin:: PublicKey > ,
1078
- ) -> SatisfiedConstraints < ' elem , ' stack , F >
1118
+ ms : & ' elem Miniscript < bitcoin:: PublicKey , Legacy > ,
1119
+ ) -> SatisfiedConstraintsIter < ' elem , ' stack , Legacy , F >
1079
1120
where
1080
1121
F : FnMut ( & bitcoin:: PublicKey , BitcoinSig ) -> bool ,
1081
1122
{
1082
- SatisfiedConstraints {
1123
+ SatisfiedConstraintsIter {
1083
1124
verify_sig : verify_fn,
1084
1125
stack : stack,
1085
1126
public_key : None ,
0 commit comments