1515use bitcoin:: hashes:: { hash160, ripemd160, sha256, sha256d, Hash } ;
1616use bitcoin:: { self , secp256k1} ;
1717use fmt;
18+ use miniscript:: { Any , Legacy , ScriptContext , Segwitv0 } ;
1819use Descriptor ;
1920use Terminal ;
2021use { error, Miniscript } ;
@@ -200,9 +201,9 @@ pub enum SatisfiedConstraint<'desc, 'stack> {
200201///the top of the stack, we need to decide whether to execute right child or not.
201202///This is also useful for wrappers and thresholds which push a value on the stack
202203///depending on evaluation of the children.
203- struct NodeEvaluationState < ' desc > {
204+ struct NodeEvaluationState < ' desc , Ctx : ScriptContext > {
204205 ///The node which is being evaluated
205- node : & ' desc Miniscript < bitcoin:: PublicKey > ,
206+ node : & ' desc Miniscript < bitcoin:: PublicKey , Ctx > ,
206207 ///number of children evaluated
207208 n_evaluated : usize ,
208209 ///number of children satisfied
@@ -217,24 +218,35 @@ struct NodeEvaluationState<'desc> {
217218/// In case the script would abort on the given witness stack OR if the entire
218219/// script is dissatisfied, this would return keep on returning values
219220///_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+ > {
221227 verify_sig : F ,
222228 public_key : Option < & ' desc bitcoin:: PublicKey > ,
223- state : Vec < NodeEvaluationState < ' desc > > ,
229+ state : Vec < NodeEvaluationState < ' desc , Ctx > > ,
224230 stack : Stack < ' stack > ,
225231 age : u32 ,
226232 height : u32 ,
227233 has_errored : bool ,
228234}
229235
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+ }
230241/// Stack Data structure representing the stack input to Miniscript. This Stack
231242/// is created from the combination of ScriptSig and Witness stack.
232243#[ derive( Clone , PartialEq , Eq , PartialOrd , Ord , Debug , Hash ) ]
233244pub struct Stack < ' stack > ( pub Vec < StackElement < ' stack > > ) ;
234245
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 >
237248where
249+ Ctx : ScriptContext ,
238250 F : FnMut ( & bitcoin:: PublicKey , BitcoinSig ) -> bool ,
239251{
240252 type Item = Result < SatisfiedConstraint < ' desc , ' stack > , Error > ;
@@ -257,36 +269,21 @@ impl<'desc, 'stack, F> SatisfiedConstraints<'desc, 'stack, F>
257269where
258270 F : FnMut ( & bitcoin:: PublicKey , BitcoinSig ) -> bool ,
259271{
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
275273 /// descriptor by a given witness stack. Because this iterator is lazy,
276274 /// it may return satisfied constraints even if these turn out to be
277275 /// irrelevant to the final (dis)satisfaction of the descriptor.
276+ /// Because the iterator is dependent evaluating the miniscript, it is
277+ /// dependent on scriptContext
278278 pub fn from_descriptor (
279279 des : & ' desc Descriptor < bitcoin:: PublicKey > ,
280280 stack : Stack < ' stack > ,
281281 verify_sig : F ,
282282 age : u32 ,
283283 height : u32 ,
284- ) -> SatisfiedConstraints < ' desc , ' stack , F > {
284+ ) -> SatisfiedConstraintsIter < ' desc , ' stack , Any , F > {
285285 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 {
290287 verify_sig : verify_sig,
291288 public_key : Some ( pk) ,
292289 state : vec ! [ ] ,
@@ -295,24 +292,67 @@ where
295292 height,
296293 has_errored : false ,
297294 } ,
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 {
302296 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 ! [ ] ,
309299 stack : stack,
310300 age,
311301 height,
312302 has_errored : false ,
313303 } ,
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+ }
314334 }
315335 }
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+ }
316356
317357 /// Helper function to step the iterator
318358 fn iter_next ( & mut self ) -> Option < Result < SatisfiedConstraint < ' desc , ' stack > , Error > > {
@@ -1019,9 +1059,10 @@ mod tests {
10191059 use bitcoin:: hashes:: { hash160, ripemd160, sha256, sha256d, Hash } ;
10201060 use bitcoin:: secp256k1:: { self , Secp256k1 , VerifyOnly } ;
10211061 use descriptor:: satisfied_constraints:: {
1022- Error , HashLockType , NodeEvaluationState , SatisfiedConstraint , SatisfiedConstraints , Stack ,
1023- StackElement ,
1062+ Error , HashLockType , NodeEvaluationState , SatisfiedConstraint , SatisfiedConstraintsIter ,
1063+ Stack , StackElement ,
10241064 } ;
1065+ use miniscript:: Legacy ;
10251066 use std:: str:: FromStr ;
10261067 use BitcoinSig ;
10271068 use Miniscript ;
@@ -1074,12 +1115,12 @@ mod tests {
10741115 fn from_stack < ' stack , ' elem , F > (
10751116 verify_fn : F ,
10761117 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 >
10791120 where
10801121 F : FnMut ( & bitcoin:: PublicKey , BitcoinSig ) -> bool ,
10811122 {
1082- SatisfiedConstraints {
1123+ SatisfiedConstraintsIter {
10831124 verify_sig : verify_fn,
10841125 stack : stack,
10851126 public_key : None ,
0 commit comments