@@ -284,31 +284,43 @@ pub fn interpreter_check<C: secp256k1::Verification>(
284
284
) -> Result < ( ) , Error > {
285
285
let utxos = prevouts ( & psbt) ?;
286
286
let utxos = & Prevouts :: All ( & utxos) ;
287
- for ( index, input) in psbt. inputs . iter ( ) . enumerate ( ) {
288
- let spk = get_scriptpubkey ( psbt, index) . map_err ( |e| Error :: InputError ( e, index) ) ?;
289
- let empty_script_sig = Script :: new ( ) ;
290
- let empty_witness = Witness :: default ( ) ;
291
- let script_sig = input. final_script_sig . as_ref ( ) . unwrap_or ( & empty_script_sig) ;
292
- let witness = input
293
- . final_script_witness
294
- . as_ref ( )
295
- . map ( |wit_slice| Witness :: from_vec ( wit_slice. to_vec ( ) ) ) // TODO: Update rust-bitcoin psbt API to use witness
296
- . unwrap_or ( empty_witness) ;
287
+ for ( index, _input) in psbt. inputs . iter ( ) . enumerate ( ) {
288
+ interpreter_inp_check ( psbt, secp, index, utxos) ?;
289
+ }
290
+ Ok ( ( ) )
291
+ }
297
292
298
- // Now look at all the satisfied constraints. If everything is filled in
299
- // corrected, there should be no errors
300
- // Interpreter check
301
- {
302
- let cltv = psbt. unsigned_tx . lock_time ;
303
- let csv = psbt. unsigned_tx . input [ index] . sequence ;
304
- let interpreter =
305
- interpreter:: Interpreter :: from_txdata ( spk, & script_sig, & witness, cltv, csv)
306
- . map_err ( |e| Error :: InputError ( InputError :: Interpreter ( e) , index) ) ?;
307
- let iter = interpreter. iter ( secp, & psbt. unsigned_tx , index, & utxos) ;
308
- if let Some ( error) = iter. filter_map ( Result :: err) . next ( ) {
309
- return Err ( Error :: InputError ( InputError :: Interpreter ( error) , index) ) ;
310
- } ;
311
- }
293
+ // Run the miniscript interpreter on a single psbt input
294
+ fn interpreter_inp_check < C : secp256k1:: Verification > (
295
+ psbt : & Psbt ,
296
+ secp : & Secp256k1 < C > ,
297
+ index : usize ,
298
+ utxos : & Prevouts ,
299
+ ) -> Result < ( ) , Error > {
300
+ let input = & psbt. inputs [ index] ;
301
+ let spk = get_scriptpubkey ( psbt, index) . map_err ( |e| Error :: InputError ( e, index) ) ?;
302
+ let empty_script_sig = Script :: new ( ) ;
303
+ let empty_witness = Witness :: default ( ) ;
304
+ let script_sig = input. final_script_sig . as_ref ( ) . unwrap_or ( & empty_script_sig) ;
305
+ let witness = input
306
+ . final_script_witness
307
+ . as_ref ( )
308
+ . map ( |wit_slice| Witness :: from_vec ( wit_slice. to_vec ( ) ) ) // TODO: Update rust-bitcoin psbt API to use witness
309
+ . unwrap_or ( empty_witness) ;
310
+
311
+ // Now look at all the satisfied constraints. If everything is filled in
312
+ // corrected, there should be no errors
313
+ // Interpreter check
314
+ {
315
+ let cltv = psbt. unsigned_tx . lock_time ;
316
+ let csv = psbt. unsigned_tx . input [ index] . sequence ;
317
+ let interpreter =
318
+ interpreter:: Interpreter :: from_txdata ( spk, & script_sig, & witness, cltv, csv)
319
+ . map_err ( |e| Error :: InputError ( InputError :: Interpreter ( e) , index) ) ?;
320
+ let iter = interpreter. iter ( secp, & psbt. unsigned_tx , index, & utxos) ;
321
+ if let Some ( error) = iter. filter_map ( Result :: err) . next ( ) {
322
+ return Err ( Error :: InputError ( InputError :: Interpreter ( error) , index) ) ;
323
+ } ;
312
324
}
313
325
Ok ( ( ) )
314
326
}
@@ -347,30 +359,47 @@ pub fn finalize_helper<C: secp256k1::Verification>(
347
359
348
360
// Actually construct the witnesses
349
361
for index in 0 ..psbt. inputs . len ( ) {
350
- let ( witness, script_sig) = {
351
- let spk = get_scriptpubkey ( psbt, index) . map_err ( |e| Error :: InputError ( e, index) ) ?;
352
- let sat = PsbtInputSatisfier :: new ( & psbt, index) ;
362
+ finalize_input ( psbt, index, secp, allow_mall) ?;
363
+ }
364
+ // Double check everything with the interpreter
365
+ // This only checks whether the script will be executed
366
+ // correctly by the bitcoin interpreter under the current
367
+ // psbt context.
368
+ interpreter_check ( & psbt, secp) ?;
369
+ Ok ( ( ) )
370
+ }
353
371
354
- if spk. is_v1_p2tr ( ) {
355
- // Deal with tr case separately, unfortunately we cannot infer the full descriptor for Tr
356
- let wit = construct_tap_witness ( spk, & sat, allow_mall)
357
- . map_err ( |e| Error :: InputError ( e, index) ) ?;
358
- ( wit, Script :: new ( ) )
359
- } else {
360
- // Get a descriptor for this input.
361
- let desc = get_descriptor ( & psbt, index) . map_err ( |e| Error :: InputError ( e, index) ) ?;
372
+ pub ( super ) fn finalize_input < C : secp256k1:: Verification > (
373
+ psbt : & mut Psbt ,
374
+ index : usize ,
375
+ secp : & Secp256k1 < C > ,
376
+ allow_mall : bool ,
377
+ ) -> Result < ( ) , super :: Error > {
378
+ let ( witness, script_sig) = {
379
+ let spk = get_scriptpubkey ( psbt, index) . map_err ( |e| Error :: InputError ( e, index) ) ?;
380
+ let sat = PsbtInputSatisfier :: new ( & psbt, index) ;
362
381
363
- //generate the satisfaction witness and scriptsig
364
- let sat = PsbtInputSatisfier :: new ( & psbt, index) ;
365
- if !allow_mall {
366
- desc. get_satisfaction ( sat)
367
- } else {
368
- desc. get_satisfaction_mall ( sat)
369
- }
370
- . map_err ( |e| Error :: InputError ( InputError :: MiniscriptError ( e) , index) ) ?
382
+ if spk. is_v1_p2tr ( ) {
383
+ // Deal with tr case separately, unfortunately we cannot infer the full descriptor for Tr
384
+ let wit = construct_tap_witness ( spk, & sat, allow_mall)
385
+ . map_err ( |e| Error :: InputError ( e, index) ) ?;
386
+ ( wit, Script :: new ( ) )
387
+ } else {
388
+ // Get a descriptor for this input.
389
+ let desc = get_descriptor ( & psbt, index) . map_err ( |e| Error :: InputError ( e, index) ) ?;
390
+
391
+ //generate the satisfaction witness and scriptsig
392
+ let sat = PsbtInputSatisfier :: new ( & psbt, index) ;
393
+ if !allow_mall {
394
+ desc. get_satisfaction ( sat)
395
+ } else {
396
+ desc. get_satisfaction_mall ( sat)
371
397
}
372
- } ;
398
+ . map_err ( |e| Error :: InputError ( InputError :: MiniscriptError ( e) , index) ) ?
399
+ }
400
+ } ;
373
401
402
+ {
374
403
let input = & mut psbt. inputs [ index] ;
375
404
//Fill in the satisfactions
376
405
input. final_script_sig = if script_sig. is_empty ( ) {
@@ -403,11 +432,10 @@ pub fn finalize_helper<C: secp256k1::Verification>(
403
432
input. tap_internal_key = None ; // x017
404
433
input. tap_merkle_root = None ; // 0x018
405
434
}
406
- // Double check everything with the interpreter
407
- // This only checks whether the script will be executed
408
- // correctly by the bitcoin interpreter under the current
409
- // psbt context.
410
- interpreter_check ( & psbt, secp) ?;
435
+ let utxos = prevouts ( & psbt) ?;
436
+ let utxos = & Prevouts :: All ( & utxos) ;
437
+ interpreter_inp_check ( psbt, secp, index, utxos) ?;
438
+
411
439
Ok ( ( ) )
412
440
}
413
441
0 commit comments