77//! encoding in Bitcoin script, as well as a datatype. Full details
88//! are given on the Miniscript website.
99
10- use core:: str:: FromStr ;
11-
12- use bitcoin:: hashes:: { hash160, Hash } ;
10+ use bitcoin:: hashes:: Hash ;
1311use bitcoin:: { absolute, opcodes, script} ;
1412use sync:: Arc ;
1513
@@ -33,7 +31,7 @@ impl<Pk: FromStrKey, Ctx: ScriptContext> crate::expression::FromTree for Termina
3331 let binary =
3432 |node : & expression:: Tree , name, termfn : fn ( _, _) -> Self | -> Result < Self , Error > {
3533 node. verify_binary ( name)
36- . map_err ( crate :: ParseError :: Tree )
34+ . map_err ( From :: from )
3735 . map_err ( Error :: Parse )
3836 . and_then ( |( x, y) | {
3937 let x = Arc :: < Miniscript < Pk , Ctx > > :: from_tree ( x) ?;
@@ -43,70 +41,97 @@ impl<Pk: FromStrKey, Ctx: ScriptContext> crate::expression::FromTree for Termina
4341 } ;
4442
4543 let ( frag_name, frag_wrap) = super :: split_expression_name ( top. name ) ?;
46- let unwrapped = match ( frag_name, top. args . len ( ) ) {
47- ( "expr_raw_pkh" , 1 ) => expression:: terminal ( & top. args [ 0 ] , |x| {
48- hash160:: Hash :: from_str ( x) . map ( Terminal :: RawPkH )
49- } ) ,
50- ( "pk_k" , 1 ) => {
51- expression:: terminal ( & top. args [ 0 ] , |x| Pk :: from_str ( x) . map ( Terminal :: PkK ) )
52- }
53- ( "pk_h" , 1 ) => {
54- expression:: terminal ( & top. args [ 0 ] , |x| Pk :: from_str ( x) . map ( Terminal :: PkH ) )
55- }
56- ( "after" , 1 ) => expression:: terminal ( & top. args [ 0 ] , |x| {
44+ let unwrapped = match frag_name {
45+ "expr_raw_pkh" => top
46+ . verify_terminal_parent ( "expr_raw_pkh" , "public key hash" )
47+ . map ( Terminal :: RawPkH )
48+ . map_err ( Error :: Parse ) ,
49+ "pk_k" => top
50+ . verify_terminal_parent ( "pk_k" , "public key" )
51+ . map ( Terminal :: PkK )
52+ . map_err ( Error :: Parse ) ,
53+ "pk_h" => top
54+ . verify_terminal_parent ( "pk_h" , "public key" )
55+ . map ( Terminal :: PkH )
56+ . map_err ( Error :: Parse ) ,
57+ "after" => expression:: terminal ( & top. args [ 0 ] , |x| {
5758 expression:: parse_num ( x)
5859 . and_then ( |x| AbsLockTime :: from_consensus ( x) . map_err ( Error :: AbsoluteLockTime ) )
5960 . map ( Terminal :: After )
6061 } ) ,
61- ( "older" , 1 ) => expression:: terminal ( & top. args [ 0 ] , |x| {
62+ "older" => expression:: terminal ( & top. args [ 0 ] , |x| {
6263 expression:: parse_num ( x)
6364 . and_then ( |x| RelLockTime :: from_consensus ( x) . map_err ( Error :: RelativeLockTime ) )
6465 . map ( Terminal :: Older )
6566 } ) ,
66- ( "sha256" , 1 ) => expression:: terminal ( & top. args [ 0 ] , |x| {
67- Pk :: Sha256 :: from_str ( x) . map ( Terminal :: Sha256 )
68- } ) ,
69- ( "hash256" , 1 ) => expression:: terminal ( & top. args [ 0 ] , |x| {
70- Pk :: Hash256 :: from_str ( x) . map ( Terminal :: Hash256 )
71- } ) ,
72- ( "ripemd160" , 1 ) => expression:: terminal ( & top. args [ 0 ] , |x| {
73- Pk :: Ripemd160 :: from_str ( x) . map ( Terminal :: Ripemd160 )
74- } ) ,
75- ( "hash160" , 1 ) => expression:: terminal ( & top. args [ 0 ] , |x| {
76- Pk :: Hash160 :: from_str ( x) . map ( Terminal :: Hash160 )
77- } ) ,
78- ( "1" , 0 ) => Ok ( Terminal :: True ) ,
79- ( "0" , 0 ) => Ok ( Terminal :: False ) ,
80- ( "and_v" , _) => binary ( top, "and_v" , Terminal :: AndV ) ,
81- ( "and_b" , _) => binary ( top, "and_b" , Terminal :: AndB ) ,
82- ( "and_n" , 2 ) => Ok ( Terminal :: AndOr (
83- expression:: FromTree :: from_tree ( & top. args [ 0 ] ) ?,
84- expression:: FromTree :: from_tree ( & top. args [ 1 ] ) ?,
85- Arc :: new ( Miniscript :: FALSE ) ,
86- ) ) ,
87- ( "andor" , 3 ) => Ok ( Terminal :: AndOr (
88- expression:: FromTree :: from_tree ( & top. args [ 0 ] ) ?,
89- expression:: FromTree :: from_tree ( & top. args [ 1 ] ) ?,
90- expression:: FromTree :: from_tree ( & top. args [ 2 ] ) ?,
91- ) ) ,
92- ( "or_b" , _) => binary ( top, "or_b" , Terminal :: OrB ) ,
93- ( "or_d" , _) => binary ( top, "or_d" , Terminal :: OrD ) ,
94- ( "or_c" , _) => binary ( top, "or_c" , Terminal :: OrC ) ,
95- ( "or_i" , _) => binary ( top, "or_i" , Terminal :: OrI ) ,
96- ( "thresh" , _) => top
67+ "sha256" => top
68+ . verify_terminal_parent ( "sha256" , "hash" )
69+ . map ( Terminal :: Sha256 )
70+ . map_err ( Error :: Parse ) ,
71+ "hash256" => top
72+ . verify_terminal_parent ( "hash256" , "hash" )
73+ . map ( Terminal :: Hash256 )
74+ . map_err ( Error :: Parse ) ,
75+ "ripemd160" => top
76+ . verify_terminal_parent ( "ripemd160" , "hash" )
77+ . map ( Terminal :: Ripemd160 )
78+ . map_err ( Error :: Parse ) ,
79+ "hash160" => top
80+ . verify_terminal_parent ( "hash160" , "hash" )
81+ . map ( Terminal :: Hash160 )
82+ . map_err ( Error :: Parse ) ,
83+ "1" => {
84+ top. verify_n_children ( "1" , 0 ..=0 )
85+ . map_err ( From :: from)
86+ . map_err ( Error :: Parse ) ?;
87+ Ok ( Terminal :: True )
88+ }
89+ "0" => {
90+ top. verify_n_children ( "0" , 0 ..=0 )
91+ . map_err ( From :: from)
92+ . map_err ( Error :: Parse ) ?;
93+ Ok ( Terminal :: False )
94+ }
95+ "and_v" => binary ( top, "and_v" , Terminal :: AndV ) ,
96+ "and_b" => binary ( top, "and_b" , Terminal :: AndB ) ,
97+ "and_n" => {
98+ binary ( top, "and_n" , |x, y| Terminal :: AndOr ( x, y, Arc :: new ( Miniscript :: FALSE ) ) )
99+ }
100+ "andor" => {
101+ top. verify_n_children ( "andor" , 3 ..=3 )
102+ . map_err ( From :: from)
103+ . map_err ( Error :: Parse ) ?;
104+ let x = Arc :: < Miniscript < Pk , Ctx > > :: from_tree ( & top. args [ 0 ] ) ?;
105+ let y = Arc :: < Miniscript < Pk , Ctx > > :: from_tree ( & top. args [ 1 ] ) ?;
106+ let z = Arc :: < Miniscript < Pk , Ctx > > :: from_tree ( & top. args [ 2 ] ) ?;
107+ Ok ( Terminal :: AndOr ( x, y, z) )
108+ }
109+ "or_b" => binary ( top, "or_b" , Terminal :: OrB ) ,
110+ "or_d" => binary ( top, "or_d" , Terminal :: OrD ) ,
111+ "or_c" => binary ( top, "or_c" , Terminal :: OrC ) ,
112+ "or_i" => binary ( top, "or_i" , Terminal :: OrI ) ,
113+ "thresh" => top
97114 . to_null_threshold ( )
98115 . map_err ( Error :: ParseThreshold ) ?
99116 . translate_by_index ( |i| Miniscript :: from_tree ( & top. args [ 1 + i] ) . map ( Arc :: new) )
100117 . map ( Terminal :: Thresh ) ,
101- ( "multi" , _ ) => top
118+ "multi" => top
102119 . to_null_threshold ( )
103120 . map_err ( Error :: ParseThreshold ) ?
104- . translate_by_index ( |i| expression:: terminal ( & top. args [ 1 + i] , Pk :: from_str) )
121+ . translate_by_index ( |i| {
122+ top. args [ 1 + i]
123+ . verify_terminal ( "public key" )
124+ . map_err ( Error :: Parse )
125+ } )
105126 . map ( Terminal :: Multi ) ,
106- ( "multi_a" , _ ) => top
127+ "multi_a" => top
107128 . to_null_threshold ( )
108129 . map_err ( Error :: ParseThreshold ) ?
109- . translate_by_index ( |i| expression:: terminal ( & top. args [ 1 + i] , Pk :: from_str) )
130+ . translate_by_index ( |i| {
131+ top. args [ 1 + i]
132+ . verify_terminal ( "public key" )
133+ . map_err ( Error :: Parse )
134+ } )
110135 . map ( Terminal :: MultiA ) ,
111136 _ => Err ( Error :: Unexpected ( format ! (
112137 "{}({} args) while parsing Miniscript" ,
0 commit comments