@@ -105,10 +105,13 @@ pub enum SatisfierError {
105
105
AssemblyFailed ( crate :: bit_machine:: ExecutionError ) ,
106
106
}
107
107
108
- #[ derive( Clone , Debug ) ]
109
- struct SatResult {
110
- serialization : Hiding < Arc < WitnessNode < Elements > > > ,
111
- is_satisfied : bool ,
108
+ type SatResult = Hiding < Arc < WitnessNode < Elements > > > ;
109
+
110
+ fn ok_if ( condition : bool , expr : SatResult ) -> SatResult {
111
+ match condition {
112
+ true => expr,
113
+ false => expr. hide ( ) ,
114
+ }
112
115
}
113
116
114
117
impl < Pk : ToXOnlyPubkey > Policy < Pk > {
@@ -117,127 +120,97 @@ impl<Pk: ToXOnlyPubkey> Policy<Pk> {
117
120
inference_context : & types:: Context ,
118
121
satisfier : & S ,
119
122
) -> Result < SatResult , SatisfierError > {
120
- let node = match * self {
121
- Policy :: Unsatisfiable ( entropy) => SatResult {
122
- serialization : super :: serialize:: unsatisfiable ( inference_context, entropy) ,
123
- is_satisfied : false ,
124
- } ,
125
- Policy :: Trivial => SatResult {
126
- serialization : super :: serialize:: trivial ( inference_context) ,
127
- is_satisfied : true ,
128
- } ,
123
+ let node: SatResult = match * self {
124
+ Policy :: Unsatisfiable ( entropy) => {
125
+ super :: serialize:: unsatisfiable :: < SatResult > ( inference_context, entropy) . hide ( )
126
+ }
127
+ Policy :: Trivial => super :: serialize:: trivial ( inference_context) ,
129
128
Policy :: Key ( ref key) => {
130
129
let signature = satisfier
131
130
. lookup_tap_leaf_script_sig ( key, & TapLeafHash :: all_zeros ( ) )
132
131
. map ( |sig| sig. sig . serialize ( ) )
133
132
. map ( Value :: u512) ;
134
- SatResult {
135
- is_satisfied : signature. is_some ( ) ,
136
- serialization : super :: serialize:: key ( inference_context, key, signature) ,
137
- }
133
+ ok_if (
134
+ signature. is_some ( ) ,
135
+ super :: serialize:: key ( inference_context, key, signature) ,
136
+ )
138
137
}
139
138
Policy :: After ( n) => {
140
139
let height = Height :: from_consensus ( n) . expect ( "timelock is valid" ) ;
141
- SatResult {
142
- serialization : super :: serialize :: after ( inference_context , n ) ,
143
- is_satisfied : satisfier . check_after ( elements :: LockTime :: Blocks ( height ) ) ,
144
- }
140
+ ok_if (
141
+ satisfier . check_after ( elements :: LockTime :: Blocks ( height ) ) ,
142
+ super :: serialize :: after ( inference_context , n ) ,
143
+ )
145
144
}
146
- Policy :: Older ( n) => SatResult {
147
- serialization : super :: serialize :: older ( inference_context , n ) ,
148
- is_satisfied : satisfier . check_older ( elements :: Sequence ( n . into ( ) ) ) ,
149
- } ,
145
+ Policy :: Older ( n) => ok_if (
146
+ satisfier . check_older ( elements :: Sequence ( n . into ( ) ) ) ,
147
+ super :: serialize :: older ( inference_context , n ) ,
148
+ ) ,
150
149
Policy :: Sha256 ( ref hash) => {
151
150
let preimage = satisfier. lookup_sha256 ( hash) . map ( Value :: u256) ;
152
- SatResult {
153
- is_satisfied : preimage. is_some ( ) ,
154
- serialization : super :: serialize:: sha256 :: < Pk , _ , _ > (
155
- inference_context,
156
- hash,
157
- preimage,
158
- ) ,
159
- }
151
+ ok_if (
152
+ preimage. is_some ( ) ,
153
+ super :: serialize:: sha256 :: < Pk , _ , _ > ( inference_context, hash, preimage) ,
154
+ )
160
155
}
161
156
Policy :: And {
162
157
ref left,
163
158
ref right,
164
159
} => {
165
- let SatResult {
166
- serialization : left,
167
- is_satisfied : left_ok,
168
- } = left. satisfy_internal ( inference_context, satisfier) ?;
169
- let SatResult {
170
- serialization : right,
171
- is_satisfied : right_ok,
172
- } = right. satisfy_internal ( inference_context, satisfier) ?;
173
- SatResult {
174
- serialization : super :: serialize:: and ( & left, & right) ,
175
- is_satisfied : left_ok && right_ok,
176
- }
160
+ let left_res = left. satisfy_internal ( inference_context, satisfier) ?;
161
+ let right_res = right. satisfy_internal ( inference_context, satisfier) ?;
162
+ super :: serialize:: and ( & left_res, & right_res)
177
163
}
178
164
Policy :: Or {
179
165
ref left,
180
166
ref right,
181
167
} => {
182
- let SatResult {
183
- serialization : left,
184
- is_satisfied : left_ok,
185
- } = left. satisfy_internal ( inference_context, satisfier) ?;
186
- let SatResult {
187
- serialization : right,
188
- is_satisfied : right_ok,
189
- } = right. satisfy_internal ( inference_context, satisfier) ?;
190
- let take_right = match ( left_ok, right_ok) {
191
- ( false , false ) => {
168
+ let left_res = left. satisfy_internal ( inference_context, satisfier) ?;
169
+ let right_res = right. satisfy_internal ( inference_context, satisfier) ?;
170
+ let take_right = match ( left_res. as_node ( ) , right_res. as_node ( ) ) {
171
+ ( Some ( left) , Some ( right) ) => {
192
172
let left_cost = left
193
- . as_node ( )
194
- . expect ( "node exists if satisfiable" )
195
173
. finalize_unpruned ( )
196
174
. expect ( "serialization should be sound" )
197
175
. bounds ( )
198
176
. cost ;
199
177
let right_cost = right
200
- . as_node ( )
201
- . expect ( "node exists if satisfiable" )
202
178
. finalize_unpruned ( )
203
179
. expect ( "serialization should be sound" )
204
180
. bounds ( )
205
181
. cost ;
206
182
right_cost < left_cost
207
183
}
208
- ( false , true ) => true ,
209
- ( true , false ) => false ,
184
+ ( None , Some ( .. ) ) => true ,
185
+ ( Some ( .. ) , None ) => false ,
210
186
// If both children are unsatisfiable, then the choice doesn't matter.
211
187
// The entire expression will be pruned out.
212
- ( true , true ) => false ,
188
+ ( None , None ) => false ,
213
189
} ;
214
190
215
- let serialization = if take_right {
216
- super :: serialize:: or ( & left , & right , Some ( Value :: u1 ( 1 ) ) )
191
+ let ret = if take_right {
192
+ super :: serialize:: or ( & left_res , & right_res , Some ( Value :: u1 ( 1 ) ) )
217
193
} else {
218
- super :: serialize:: or ( & left , & right , Some ( Value :: u1 ( 0 ) ) )
194
+ super :: serialize:: or ( & left_res , & right_res , Some ( Value :: u1 ( 0 ) ) )
219
195
} ;
220
- SatResult {
221
- serialization ,
222
- is_satisfied : left_ok || right_ok ,
223
- }
196
+ ok_if (
197
+ left_res . as_node ( ) . is_some ( ) || right_res . as_node ( ) . is_some ( ) ,
198
+ ret ,
199
+ )
224
200
}
225
201
Policy :: Threshold ( k, ref subs) => {
226
- let node_results : Vec < SatResult > = subs
202
+ let subs_res : Vec < SatResult > = subs
227
203
. iter ( )
228
204
. map ( |sub| sub. satisfy_internal ( inference_context, satisfier) )
229
205
. collect :: < Result < _ , SatisfierError > > ( ) ?;
230
- let costs: Vec < Cost > = node_results
206
+ let costs: Vec < Cost > = subs_res
231
207
. iter ( )
232
- . map ( |result| match result. is_satisfied {
233
- true => result
234
- . serialization
235
- . as_node ( )
236
- . expect ( "node exists if satisfiable" )
208
+ . map ( |result| match result. as_node ( ) {
209
+ Some ( node) => node
237
210
. finalize_unpruned ( )
238
211
. map ( |redeem| redeem. bounds ( ) . cost )
239
212
. unwrap_or ( Cost :: CONSENSUS_MAX ) ,
240
- false => Cost :: CONSENSUS_MAX ,
213
+ None => Cost :: CONSENSUS_MAX ,
241
214
} )
242
215
. collect ( ) ;
243
216
let selected_node_indices = {
@@ -248,30 +221,19 @@ impl<Pk: ToXOnlyPubkey> Policy<Pk> {
248
221
} ;
249
222
let all_selected_ok = selected_node_indices
250
223
. iter ( )
251
- . all ( |& i| node_results [ i] . is_satisfied ) ;
252
- let witness_bits: Vec < Option < Value > > = ( 0 ..node_results . len ( ) )
224
+ . all ( |& i| subs_res [ i] . as_node ( ) . is_some ( ) ) ;
225
+ let witness_bits: Vec < Option < Value > > = ( 0 ..subs_res . len ( ) )
253
226
. map ( |i| Some ( Value :: u1 ( u8:: from ( selected_node_indices. contains ( & i) ) ) ) )
254
227
. collect ( ) ;
255
-
256
228
let k = u32:: try_from ( k) . expect ( "k should be less than 2^32" ) ;
257
- let nodes: Vec < _ > = node_results
258
- . into_iter ( )
259
- . map ( |result| result. serialization )
260
- . collect ( ) ;
261
- SatResult {
262
- serialization : super :: serialize:: threshold ( k, & nodes, & witness_bits) ,
263
- is_satisfied : all_selected_ok,
264
- }
229
+ ok_if (
230
+ all_selected_ok,
231
+ super :: serialize:: threshold ( k, & subs_res, & witness_bits) ,
232
+ )
265
233
}
266
234
Policy :: Assembly ( cmr) => match satisfier. lookup_asm_program ( cmr) {
267
- Some ( program) => SatResult {
268
- serialization : Hiding :: from ( program) ,
269
- is_satisfied : true ,
270
- } ,
271
- None => SatResult {
272
- serialization : Hiding :: hidden ( cmr, inference_context. shallow_clone ( ) ) ,
273
- is_satisfied : false ,
274
- } ,
235
+ Some ( program) => Hiding :: from ( program) ,
236
+ None => Hiding :: hidden ( cmr, inference_context. shallow_clone ( ) ) ,
275
237
} ,
276
238
} ;
277
239
Ok ( node)
@@ -286,17 +248,14 @@ impl<Pk: ToXOnlyPubkey> Policy<Pk> {
286
248
satisfier : & S ,
287
249
env : & ElementsEnv < Arc < elements:: Transaction > > ,
288
250
) -> Result < Arc < RedeemNode < Elements > > , SatisfierError > {
289
- let SatResult {
290
- serialization : witness_program,
291
- is_satisfied,
292
- } = self . satisfy_internal ( & types:: Context :: new ( ) , satisfier) ?;
293
- match ( witness_program. get_node ( ) , is_satisfied) {
294
- ( Some ( program) , true ) => program
251
+ let result = self . satisfy_internal ( & types:: Context :: new ( ) , satisfier) ?;
252
+ match result. get_node ( ) {
253
+ Some ( program) => program
295
254
. finalize_unpruned ( )
296
255
. expect ( "serialization should be sound" )
297
256
. prune ( env)
298
257
. map_err ( SatisfierError :: AssemblyFailed ) , // execution fails iff assembly fragment fails
299
- _ => Err ( SatisfierError :: Unsatisfiable ) ,
258
+ None => Err ( SatisfierError :: Unsatisfiable ) ,
300
259
}
301
260
}
302
261
}
0 commit comments