@@ -72,10 +72,6 @@ pub enum Policy<Pk: MiniscriptKey> {
72
72
/// Detailed error type for concrete policies.
73
73
#[ derive( Copy , Clone , PartialEq , Eq , Debug , Hash ) ]
74
74
pub enum PolicyError {
75
- /// `And` fragments only support two args.
76
- NonBinaryArgAnd ,
77
- /// `Or` fragments only support two args.
78
- NonBinaryArgOr ,
79
75
/// Cannot lift policies that have a combination of height and timelocks.
80
76
HeightTimelockCombination ,
81
77
/// Duplicate Public Keys.
@@ -100,10 +96,6 @@ pub enum DescriptorCtx<Pk> {
100
96
impl fmt:: Display for PolicyError {
101
97
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
102
98
match * self {
103
- PolicyError :: NonBinaryArgAnd => {
104
- f. write_str ( "And policy fragment must take 2 arguments" )
105
- }
106
- PolicyError :: NonBinaryArgOr => f. write_str ( "Or policy fragment must take 2 arguments" ) ,
107
99
PolicyError :: HeightTimelockCombination => {
108
100
f. write_str ( "Cannot lift policies that have a heightlock and timelock combination" )
109
101
}
@@ -118,7 +110,7 @@ impl error::Error for PolicyError {
118
110
use self :: PolicyError :: * ;
119
111
120
112
match self {
121
- NonBinaryArgAnd | NonBinaryArgOr | HeightTimelockCombination | DuplicatePubKeys => None ,
113
+ HeightTimelockCombination | DuplicatePubKeys => None ,
122
114
}
123
115
}
124
116
}
@@ -157,6 +149,26 @@ impl<'p, Pk: MiniscriptKey> Iterator for TapleafProbabilityIter<'p, Pk> {
157
149
}
158
150
159
151
impl < Pk : MiniscriptKey > Policy < Pk > {
152
+ #[ cfg( feature = "compiler" ) ]
153
+ fn check_binary_ops ( & self ) -> Result < ( ) , CompilerError > {
154
+ for policy in self . pre_order_iter ( ) {
155
+ match * policy {
156
+ Policy :: And ( ref subs) => {
157
+ if subs. len ( ) != 2 {
158
+ return Err ( CompilerError :: NonBinaryArgAnd ) ;
159
+ }
160
+ }
161
+ Policy :: Or ( ref subs) => {
162
+ if subs. len ( ) != 2 {
163
+ return Err ( CompilerError :: NonBinaryArgOr ) ;
164
+ }
165
+ }
166
+ _ => { }
167
+ }
168
+ }
169
+ Ok ( ( ) )
170
+ }
171
+
160
172
/// Flattens the [`Policy`] tree structure into an iterator of tuples `(leaf script, leaf probability)`
161
173
/// with leaf probabilities corresponding to odds for each sub-branch in the policy.
162
174
/// We calculate the probability of selecting the sub-branch at every level and calculate the
@@ -223,6 +235,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
223
235
#[ cfg( feature = "compiler" ) ]
224
236
pub fn compile_tr ( & self , unspendable_key : Option < Pk > ) -> Result < Descriptor < Pk > , CompilerError > {
225
237
self . is_valid ( ) . map_err ( CompilerError :: PolicyError ) ?;
238
+ self . check_binary_ops ( ) ?;
226
239
match self . is_safe_nonmalleable ( ) {
227
240
( false , _) => Err ( CompilerError :: TopLevelNonSafe ) ,
228
241
( _, false ) => Err ( CompilerError :: ImpossibleNonMalleableCompilation ) ,
@@ -286,6 +299,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
286
299
unspendable_key : Option < Pk > ,
287
300
) -> Result < Descriptor < Pk > , Error > {
288
301
self . is_valid ( ) . map_err ( Error :: ConcretePolicy ) ?;
302
+ self . check_binary_ops ( ) ?;
289
303
match self . is_safe_nonmalleable ( ) {
290
304
( false , _) => Err ( Error :: from ( CompilerError :: TopLevelNonSafe ) ) ,
291
305
( _, false ) => Err ( Error :: from ( CompilerError :: ImpossibleNonMalleableCompilation ) ) ,
@@ -339,6 +353,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
339
353
desc_ctx : DescriptorCtx < Pk > ,
340
354
) -> Result < Descriptor < Pk > , Error > {
341
355
self . is_valid ( ) . map_err ( Error :: ConcretePolicy ) ?;
356
+ self . check_binary_ops ( ) ?;
342
357
match self . is_safe_nonmalleable ( ) {
343
358
( false , _) => Err ( Error :: from ( CompilerError :: TopLevelNonSafe ) ) ,
344
359
( _, false ) => Err ( Error :: from ( CompilerError :: ImpossibleNonMalleableCompilation ) ) ,
@@ -364,6 +379,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
364
379
#[ cfg( feature = "compiler" ) ]
365
380
pub fn compile < Ctx : ScriptContext > ( & self ) -> Result < Miniscript < Pk , Ctx > , CompilerError > {
366
381
self . is_valid ( ) ?;
382
+ self . check_binary_ops ( ) ?;
367
383
match self . is_safe_nonmalleable ( ) {
368
384
( false , _) => Err ( CompilerError :: TopLevelNonSafe ) ,
369
385
( _, false ) => Err ( CompilerError :: ImpossibleNonMalleableCompilation ) ,
@@ -684,26 +700,8 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
684
700
/// Validity condition also checks whether there is a possible satisfaction
685
701
/// combination of timelocks and heightlocks
686
702
pub fn is_valid ( & self ) -> Result < ( ) , PolicyError > {
687
- use Policy :: * ;
688
-
689
703
self . check_timelocks ( ) ?;
690
704
self . check_duplicate_keys ( ) ?;
691
-
692
- for policy in self . pre_order_iter ( ) {
693
- match * policy {
694
- And ( ref subs) => {
695
- if subs. len ( ) != 2 {
696
- return Err ( PolicyError :: NonBinaryArgAnd ) ;
697
- }
698
- }
699
- Or ( ref subs) => {
700
- if subs. len ( ) != 2 {
701
- return Err ( PolicyError :: NonBinaryArgOr ) ;
702
- }
703
- }
704
- _ => { }
705
- }
706
- }
707
705
Ok ( ( ) )
708
706
}
709
707
0 commit comments