@@ -284,79 +284,104 @@ impl<Pk: FromStrKey> str::FromStr for Policy<Pk> {
284284serde_string_impl_pk ! ( Policy , "a miniscript semantic policy" ) ;
285285
286286impl < 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+ }
342305 }
343- "thresh" => {
344- let thresh = top. verify_threshold ( |sub| Self :: from_tree ( sub) . map ( Arc :: new) ) ?;
345306
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 )
349319 }
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) )
352351 }
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 ( ) ) ) ?;
353362
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) ) ;
359381 }
382+
383+ assert_eq ! ( stack. len( ) , 1 ) ;
384+ Ok ( Arc :: try_unwrap ( stack. pop ( ) . unwrap ( ) ) . unwrap ( ) )
360385 }
361386}
362387
0 commit comments