7
7
//! encoding in Bitcoin script, as well as a datatype. Full details
8
8
//! are given on the Miniscript website.
9
9
10
- use core:: str:: FromStr ;
11
-
12
- use bitcoin:: hashes:: { hash160, Hash } ;
10
+ use bitcoin:: hashes:: Hash ;
13
11
use bitcoin:: { absolute, opcodes, script} ;
14
12
use sync:: Arc ;
15
13
@@ -33,7 +31,7 @@ impl<Pk: FromStrKey, Ctx: ScriptContext> crate::expression::FromTree for Termina
33
31
let binary =
34
32
|node : & expression:: Tree , name, termfn : fn ( _, _) -> Self | -> Result < Self , Error > {
35
33
node. verify_binary ( name)
36
- . map_err ( crate :: ParseError :: Tree )
34
+ . map_err ( From :: from )
37
35
. map_err ( Error :: Parse )
38
36
. and_then ( |( x, y) | {
39
37
let x = Arc :: < Miniscript < Pk , Ctx > > :: from_tree ( x) ?;
@@ -43,70 +41,97 @@ impl<Pk: FromStrKey, Ctx: ScriptContext> crate::expression::FromTree for Termina
43
41
} ;
44
42
45
43
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| {
57
58
expression:: parse_num ( x)
58
59
. and_then ( |x| AbsLockTime :: from_consensus ( x) . map_err ( Error :: AbsoluteLockTime ) )
59
60
. map ( Terminal :: After )
60
61
} ) ,
61
- ( "older" , 1 ) => expression:: terminal ( & top. args [ 0 ] , |x| {
62
+ "older" => expression:: terminal ( & top. args [ 0 ] , |x| {
62
63
expression:: parse_num ( x)
63
64
. and_then ( |x| RelLockTime :: from_consensus ( x) . map_err ( Error :: RelativeLockTime ) )
64
65
. map ( Terminal :: Older )
65
66
} ) ,
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
97
114
. to_null_threshold ( )
98
115
. map_err ( Error :: ParseThreshold ) ?
99
116
. translate_by_index ( |i| Miniscript :: from_tree ( & top. args [ 1 + i] ) . map ( Arc :: new) )
100
117
. map ( Terminal :: Thresh ) ,
101
- ( "multi" , _ ) => top
118
+ "multi" => top
102
119
. to_null_threshold ( )
103
120
. 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
+ } )
105
126
. map ( Terminal :: Multi ) ,
106
- ( "multi_a" , _ ) => top
127
+ "multi_a" => top
107
128
. to_null_threshold ( )
108
129
. 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
+ } )
110
135
. map ( Terminal :: MultiA ) ,
111
136
_ => Err ( Error :: Unexpected ( format ! (
112
137
"{}({} args) while parsing Miniscript" ,
0 commit comments