@@ -843,100 +843,112 @@ impl<Pk: FromStrKey> str::FromStr for Policy<Pk> {
843843
844844serde_string_impl_pk ! ( Policy , "a miniscript concrete policy" ) ;
845845
846- impl < Pk : FromStrKey > Policy < Pk > {
847- /// Helper function for `from_tree` to parse subexpressions with
848- /// names of the form x@y
849- fn from_tree_prob (
850- top : expression:: TreeIterItem ,
851- allow_prob : bool ,
852- ) -> Result < ( usize , Policy < Pk > ) , Error > {
853- // When 'allow_prob' is true we parse '@' signs out of node names.
854- let ( frag_prob, frag_name) = if allow_prob {
855- top. name_separated ( '@' )
856- . map_err ( From :: from)
857- . map_err ( Error :: Parse ) ?
858- } else {
859- ( None , top. name ( ) )
860- } ;
861-
862- let frag_prob = match frag_prob {
863- None => 1 ,
864- Some ( s) => expression:: parse_num ( s)
865- . map_err ( From :: from)
866- . map_err ( Error :: Parse ) ? as usize ,
867- } ;
868-
869- match frag_name {
870- "UNSATISFIABLE" => {
871- top. verify_n_children ( "UNSATISFIABLE" , 0 ..=0 )
872- . map_err ( From :: from)
873- . map_err ( Error :: Parse ) ?;
874- Ok ( Policy :: Unsatisfiable )
875- }
876- "TRIVIAL" => {
877- top. verify_n_children ( "TRIVIAL" , 0 ..=0 )
846+ impl < Pk : FromStrKey > expression:: FromTree for Policy < Pk > {
847+ fn from_tree ( root : expression:: TreeIterItem ) -> Result < Policy < Pk > , Error > {
848+ root. verify_no_curly_braces ( )
849+ . map_err ( From :: from)
850+ . map_err ( Error :: Parse ) ?;
851+
852+ let mut stack = Vec :: < ( usize , _ ) > :: with_capacity ( 128 ) ;
853+ for node in root. pre_order_iter ( ) . rev ( ) {
854+ let allow_prob;
855+ // Before doing anything else, check if this is the inner value of a terminal.
856+ // In that case, just skip the node. Conveniently, there are no combinators
857+ // in policy that have a single child that these might be confused with (we
858+ // require and, or and thresholds to all have >1 child).
859+ if let Some ( parent) = node. parent ( ) {
860+ if parent. n_children ( ) == 1 {
861+ continue ;
862+ }
863+ let ( _, parent_name) = parent
864+ . name_separated ( '@' )
878865 . map_err ( From :: from)
879866 . map_err ( Error :: Parse ) ?;
880- Ok ( Policy :: Trivial )
867+ if node. is_first_child ( ) && parent_name == "thresh" {
868+ continue ;
869+ }
870+ allow_prob = parent_name == "or" ;
871+ } else {
872+ allow_prob = false ;
881873 }
882- "pk" => top
883- . verify_terminal_parent ( "pk" , "public key" )
884- . map ( Policy :: Key )
885- . map_err ( Error :: Parse ) ,
886- "after" => top. verify_after ( ) . map_err ( Error :: Parse ) . map ( Policy :: After ) ,
887- "older" => top. verify_older ( ) . map_err ( Error :: Parse ) . map ( Policy :: Older ) ,
888- "sha256" => top
889- . verify_terminal_parent ( "sha256" , "hash" )
890- . map ( Policy :: Sha256 )
891- . map_err ( Error :: Parse ) ,
892- "hash256" => top
893- . verify_terminal_parent ( "hash256" , "hash" )
894- . map ( Policy :: Hash256 )
895- . map_err ( Error :: Parse ) ,
896- "ripemd160" => top
897- . verify_terminal_parent ( "ripemd160" , "hash" )
898- . map ( Policy :: Ripemd160 )
899- . map_err ( Error :: Parse ) ,
900- "hash160" => top
901- . verify_terminal_parent ( "hash160" , "hash" )
902- . map ( Policy :: Hash160 )
903- . map_err ( Error :: Parse ) ,
904- "and" => {
905- top. verify_n_children ( "and" , 2 ..=2 )
874+
875+ // When 'allow_prob' is true we parse '@' signs out of node names.
876+ let ( frag_prob, frag_name) = if allow_prob {
877+ node. name_separated ( '@' )
906878 . map_err ( From :: from)
907- . map_err ( Error :: Parse ) ?;
908- let subs = top
909- . children ( )
910- . map ( |arg| Self :: from_tree ( arg) . map ( Arc :: new) )
911- . collect :: < Result < _ , Error > > ( ) ?;
912- Ok ( Policy :: And ( subs) )
913- }
914- "or" => {
915- top. verify_n_children ( "or" , 2 ..=2 )
879+ . map_err ( Error :: Parse ) ?
880+ } else {
881+ ( None , node. name ( ) )
882+ } ;
883+
884+ let frag_prob = match frag_prob {
885+ None => 1 ,
886+ Some ( s) => expression:: parse_num ( s)
916887 . map_err ( From :: from)
917- . map_err ( Error :: Parse ) ?;
918- let subs = top
919- . children ( )
920- . map ( |arg| {
921- Self :: from_tree_prob ( arg, true ) . map ( |( prob, sub) | ( prob, Arc :: new ( sub) ) )
922- } )
923- . collect :: < Result < _ , Error > > ( ) ?;
924- Ok ( Policy :: Or ( subs) )
925- }
926- "thresh" => top
927- . verify_threshold ( |sub| Self :: from_tree ( sub) . map ( Arc :: new) )
928- . map ( Self :: Thresh ) ,
929- x => Err ( Error :: Parse ( crate :: ParseError :: Tree ( crate :: ParseTreeError :: UnknownName {
930- name : x. to_owned ( ) ,
931- } ) ) ) ,
888+ . map_err ( Error :: Parse ) ? as usize ,
889+ } ;
890+
891+ let new =
892+ match frag_name {
893+ "UNSATISFIABLE" => {
894+ node. verify_n_children ( "UNSATISFIABLE" , 0 ..=0 )
895+ . map_err ( From :: from)
896+ . map_err ( Error :: Parse ) ?;
897+ Ok ( Policy :: Unsatisfiable )
898+ }
899+ "TRIVIAL" => {
900+ node. verify_n_children ( "TRIVIAL" , 0 ..=0 )
901+ . map_err ( From :: from)
902+ . map_err ( Error :: Parse ) ?;
903+ Ok ( Policy :: Trivial )
904+ }
905+ "pk" => node
906+ . verify_terminal_parent ( "pk" , "public key" )
907+ . map ( Policy :: Key )
908+ . map_err ( Error :: Parse ) ,
909+ "after" => node. verify_after ( ) . map_err ( Error :: Parse ) . map ( Policy :: After ) ,
910+ "older" => node. verify_older ( ) . map_err ( Error :: Parse ) . map ( Policy :: Older ) ,
911+ "sha256" => node
912+ . verify_terminal_parent ( "sha256" , "hash" )
913+ . map ( Policy :: Sha256 )
914+ . map_err ( Error :: Parse ) ,
915+ "hash256" => node
916+ . verify_terminal_parent ( "hash256" , "hash" )
917+ . map ( Policy :: Hash256 )
918+ . map_err ( Error :: Parse ) ,
919+ "ripemd160" => node
920+ . verify_terminal_parent ( "ripemd160" , "hash" )
921+ . map ( Policy :: Ripemd160 )
922+ . map_err ( Error :: Parse ) ,
923+ "hash160" => node
924+ . verify_terminal_parent ( "hash160" , "hash" )
925+ . map ( Policy :: Hash160 )
926+ . map_err ( Error :: Parse ) ,
927+ "and" => {
928+ node. verify_n_children ( "and" , 2 ..=2 )
929+ . map_err ( From :: from)
930+ . map_err ( Error :: Parse ) ?;
931+ Ok ( Policy :: And ( vec ! [ stack. pop( ) . unwrap( ) . 1 , stack. pop( ) . unwrap( ) . 1 ] ) )
932+ }
933+ "or" => {
934+ node. verify_n_children ( "or" , 2 ..=2 )
935+ . map_err ( From :: from)
936+ . map_err ( Error :: Parse ) ?;
937+ Ok ( Policy :: Or ( vec ! [ stack. pop( ) . unwrap( ) , stack. pop( ) . unwrap( ) ] ) )
938+ }
939+ "thresh" => node
940+ . verify_threshold ( |_| Ok ( stack. pop ( ) . unwrap ( ) . 1 ) )
941+ . map ( Self :: Thresh ) ,
942+ x => Err ( Error :: Parse ( crate :: ParseError :: Tree (
943+ crate :: ParseTreeError :: UnknownName { name : x. to_owned ( ) } ,
944+ ) ) ) ,
945+ } ?;
946+
947+ stack. push ( ( frag_prob, Arc :: new ( new) ) ) ;
932948 }
933- . map ( |res| ( frag_prob, res) )
934- }
935- }
936949
937- impl < Pk : FromStrKey > expression:: FromTree for Policy < Pk > {
938- fn from_tree ( root : expression:: TreeIterItem ) -> Result < Policy < Pk > , Error > {
939- Policy :: from_tree_prob ( root, false ) . map ( |( _, result) | result)
950+ assert_eq ! ( stack. len( ) , 1 ) ;
951+ Ok ( Arc :: try_unwrap ( stack. pop ( ) . unwrap ( ) . 1 ) . unwrap ( ) )
940952 }
941953}
942954
0 commit comments