@@ -284,79 +284,104 @@ impl<Pk: FromStrKey> str::FromStr for Policy<Pk> {
284
284
serde_string_impl_pk ! ( Policy , "a miniscript semantic policy" ) ;
285
285
286
286
impl < Pk : FromStrKey > expression:: FromTree for Policy < Pk > {
287
- fn from_tree ( top : expression:: TreeIterItem ) -> Result < Policy < Pk > , Error > {
288
- match top. name ( ) {
289
- "UNSATISFIABLE" => {
290
- top. verify_n_children ( "UNSATISFIABLE" , 0 ..=0 )
291
- . map_err ( From :: from)
292
- . map_err ( Error :: Parse ) ?;
293
- Ok ( Policy :: Unsatisfiable )
294
- }
295
- "TRIVIAL" => {
296
- top. verify_n_children ( "TRIVIAL" , 0 ..=0 )
297
- . map_err ( From :: from)
298
- . map_err ( Error :: Parse ) ?;
299
- Ok ( Policy :: Trivial )
300
- }
301
- "pk" => top
302
- . verify_terminal_parent ( "pk" , "public key" )
303
- . map ( Policy :: Key )
304
- . map_err ( Error :: Parse ) ,
305
- "after" => top. verify_after ( ) . map_err ( Error :: Parse ) . map ( Policy :: After ) ,
306
- "older" => top. verify_older ( ) . map_err ( Error :: Parse ) . map ( Policy :: Older ) ,
307
- "sha256" => top
308
- . verify_terminal_parent ( "sha256" , "hash" )
309
- . map ( Policy :: Sha256 )
310
- . map_err ( Error :: Parse ) ,
311
- "hash256" => top
312
- . verify_terminal_parent ( "hash256" , "hash" )
313
- . map ( Policy :: Hash256 )
314
- . map_err ( Error :: Parse ) ,
315
- "ripemd160" => top
316
- . verify_terminal_parent ( "ripemd160" , "hash" )
317
- . map ( Policy :: Ripemd160 )
318
- . map_err ( Error :: Parse ) ,
319
- "hash160" => top
320
- . verify_terminal_parent ( "hash160" , "hash" )
321
- . map ( Policy :: Hash160 )
322
- . map_err ( Error :: Parse ) ,
323
- "and" => {
324
- top. verify_n_children ( "and" , 2 ..)
325
- . map_err ( From :: from)
326
- . map_err ( Error :: Parse ) ?;
327
- let subs = top
328
- . children ( )
329
- . map ( |arg| Self :: from_tree ( arg) . map ( Arc :: new) )
330
- . collect :: < Result < Vec < _ > , Error > > ( ) ?;
331
- Ok ( Policy :: Thresh ( Threshold :: new ( subs. len ( ) , subs) . map_err ( Error :: Threshold ) ?) )
332
- }
333
- "or" => {
334
- top. verify_n_children ( "or" , 2 ..)
335
- . map_err ( From :: from)
336
- . map_err ( Error :: Parse ) ?;
337
- let subs = top
338
- . children ( )
339
- . map ( |arg| Self :: from_tree ( arg) . map ( Arc :: new) )
340
- . collect :: < Result < Vec < _ > , Error > > ( ) ?;
341
- Ok ( Policy :: Thresh ( Threshold :: new ( 1 , subs) . map_err ( Error :: Threshold ) ?) )
287
+ fn from_tree ( root : expression:: TreeIterItem ) -> Result < Policy < Pk > , Error > {
288
+ root. verify_no_curly_braces ( )
289
+ . map_err ( From :: from)
290
+ . map_err ( Error :: Parse ) ?;
291
+
292
+ let mut stack = Vec :: with_capacity ( 128 ) ;
293
+ for node in root. pre_order_iter ( ) . rev ( ) {
294
+ // Before doing anything else, check if this is the inner value of a terminal.
295
+ // In that case, just skip the node. Conveniently, there are no combinators
296
+ // in policy that have a single child that these might be confused with (we
297
+ // require and, or and thresholds to all have >1 child).
298
+ if let Some ( parent) = node. parent ( ) {
299
+ if parent. n_children ( ) == 1 {
300
+ continue ;
301
+ }
302
+ if node. is_first_child ( ) && parent. name ( ) == "thresh" {
303
+ continue ;
304
+ }
342
305
}
343
- "thresh" => {
344
- let thresh = top. verify_threshold ( |sub| Self :: from_tree ( sub) . map ( Arc :: new) ) ?;
345
306
346
- // thresh(1) and thresh(n) are disallowed in semantic policies
347
- if thresh. is_or ( ) {
348
- return Err ( Error :: ParseThreshold ( crate :: ParseThresholdError :: IllegalOr ) ) ;
307
+ let new = match node. name ( ) {
308
+ "UNSATISFIABLE" => {
309
+ node. verify_n_children ( "UNSATISFIABLE" , 0 ..=0 )
310
+ . map_err ( From :: from)
311
+ . map_err ( Error :: Parse ) ?;
312
+ Ok ( Policy :: Unsatisfiable )
313
+ }
314
+ "TRIVIAL" => {
315
+ node. verify_n_children ( "TRIVIAL" , 0 ..=0 )
316
+ . map_err ( From :: from)
317
+ . map_err ( Error :: Parse ) ?;
318
+ Ok ( Policy :: Trivial )
349
319
}
350
- if thresh. is_and ( ) {
351
- return Err ( Error :: ParseThreshold ( crate :: ParseThresholdError :: IllegalAnd ) ) ;
320
+ "pk" => node
321
+ . verify_terminal_parent ( "pk" , "public key" )
322
+ . map ( Policy :: Key )
323
+ . map_err ( Error :: Parse ) ,
324
+ "after" => node. verify_after ( ) . map_err ( Error :: Parse ) . map ( Policy :: After ) ,
325
+ "older" => node. verify_older ( ) . map_err ( Error :: Parse ) . map ( Policy :: Older ) ,
326
+ "sha256" => node
327
+ . verify_terminal_parent ( "sha256" , "hash" )
328
+ . map ( Policy :: Sha256 )
329
+ . map_err ( Error :: Parse ) ,
330
+ "hash256" => node
331
+ . verify_terminal_parent ( "hash256" , "hash" )
332
+ . map ( Policy :: Hash256 )
333
+ . map_err ( Error :: Parse ) ,
334
+ "ripemd160" => node
335
+ . verify_terminal_parent ( "ripemd160" , "hash" )
336
+ . map ( Policy :: Ripemd160 )
337
+ . map_err ( Error :: Parse ) ,
338
+ "hash160" => node
339
+ . verify_terminal_parent ( "hash160" , "hash" )
340
+ . map ( Policy :: Hash160 )
341
+ . map_err ( Error :: Parse ) ,
342
+ "and" => {
343
+ node. verify_n_children ( "and" , 2 ..)
344
+ . map_err ( From :: from)
345
+ . map_err ( Error :: Parse ) ?;
346
+
347
+ let child_iter = ( 0 ..node. n_children ( ) ) . map ( |_| stack. pop ( ) . unwrap ( ) ) ;
348
+ let thresh = Threshold :: from_iter ( node. n_children ( ) , child_iter)
349
+ . map_err ( Error :: Threshold ) ?;
350
+ Ok ( Policy :: Thresh ( thresh) )
352
351
}
352
+ "or" => {
353
+ node. verify_n_children ( "or" , 2 ..)
354
+ . map_err ( From :: from)
355
+ . map_err ( Error :: Parse ) ?;
356
+ let child_iter = ( 0 ..node. n_children ( ) ) . map ( |_| stack. pop ( ) . unwrap ( ) ) ;
357
+ let thresh = Threshold :: from_iter ( 1 , child_iter) . map_err ( Error :: Threshold ) ?;
358
+ Ok ( Policy :: Thresh ( thresh) )
359
+ }
360
+ "thresh" => {
361
+ let thresh = node. verify_threshold ( |_| Ok :: < _ , Error > ( stack. pop ( ) . unwrap ( ) ) ) ?;
353
362
354
- Ok ( Policy :: Thresh ( thresh) )
355
- }
356
- x => Err ( Error :: Parse ( crate :: ParseError :: Tree ( crate :: ParseTreeError :: UnknownName {
357
- name : x. to_owned ( ) ,
358
- } ) ) ) ,
363
+ // thresh(1) and thresh(n) are disallowed in semantic policies
364
+ if thresh. is_or ( ) {
365
+ return Err ( Error :: ParseThreshold ( crate :: ParseThresholdError :: IllegalOr ) ) ;
366
+ }
367
+ if thresh. is_and ( ) {
368
+ return Err ( Error :: ParseThreshold ( crate :: ParseThresholdError :: IllegalAnd ) ) ;
369
+ }
370
+
371
+ Ok ( Policy :: Thresh ( thresh) )
372
+ }
373
+ x => {
374
+ Err ( Error :: Parse ( crate :: ParseError :: Tree ( crate :: ParseTreeError :: UnknownName {
375
+ name : x. to_owned ( ) ,
376
+ } ) ) )
377
+ }
378
+ } ?;
379
+
380
+ stack. push ( Arc :: new ( new) ) ;
359
381
}
382
+
383
+ assert_eq ! ( stack. len( ) , 1 ) ;
384
+ Ok ( Arc :: try_unwrap ( stack. pop ( ) . unwrap ( ) ) . unwrap ( ) )
360
385
}
361
386
}
362
387
0 commit comments