@@ -284,31 +284,43 @@ pub fn interpreter_check<C: secp256k1::Verification>(
284284) -> Result < ( ) , Error > {
285285 let utxos = prevouts ( & psbt) ?;
286286 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+ }
297292
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+ } ;
312324 }
313325 Ok ( ( ) )
314326}
@@ -347,29 +359,46 @@ pub fn finalize_helper<C: secp256k1::Verification>(
347359
348360 // Actually construct the witnesses
349361 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+ }
353371
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) ;
362381
363- //generate the satisfaction witness and scriptsig
364- if !allow_mall {
365- desc. get_satisfaction ( PsbtInputSatisfier :: new ( & psbt, index) )
366- } else {
367- desc. get_satisfaction_mall ( PsbtInputSatisfier :: new ( & psbt, index) )
368- }
369- . 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+ if !allow_mall {
393+ desc. get_satisfaction ( PsbtInputSatisfier :: new ( & psbt, index) )
394+ } else {
395+ desc. get_satisfaction_mall ( PsbtInputSatisfier :: new ( & psbt, index) )
370396 }
371- } ;
397+ . map_err ( |e| Error :: InputError ( InputError :: MiniscriptError ( e) , index) ) ?
398+ }
399+ } ;
372400
401+ {
373402 let input = & mut psbt. inputs [ index] ;
374403 //Fill in the satisfactions
375404 input. final_script_sig = if script_sig. is_empty ( ) {
@@ -402,11 +431,10 @@ pub fn finalize_helper<C: secp256k1::Verification>(
402431 input. tap_internal_key = None ; // x017
403432 input. tap_merkle_root = None ; // 0x018
404433 }
405- // Double check everything with the interpreter
406- // This only checks whether the script will be executed
407- // correctly by the bitcoin interpreter under the current
408- // psbt context.
409- interpreter_check ( & psbt, secp) ?;
434+ let utxos = prevouts ( & psbt) ?;
435+ let utxos = & Prevouts :: All ( & utxos) ;
436+ interpreter_inp_check ( psbt, secp, index, utxos) ?;
437+
410438 Ok ( ( ) )
411439}
412440
0 commit comments