1919//! `https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki`
2020//!
2121
22+ use bitcoin:: util:: sighash:: Prevouts ;
2223use util:: { script_is_v1_tr, witness_size} ;
2324
24- use interpreter:: KeySigPair ;
25-
2625use super :: { sanity_check, Psbt } ;
2726use super :: { Error , InputError , PsbtInputSatisfier } ;
2827use bitcoin:: blockdata:: witness:: Witness ;
@@ -99,32 +98,31 @@ fn construct_tap_witness(
9998
10099// Get the scriptpubkey for the psbt input
101100fn get_scriptpubkey ( psbt : & Psbt , index : usize ) -> Result < & Script , InputError > {
102- let script_pubkey;
103- let inp = & psbt. inputs [ index] ;
104- if let Some ( ref witness_utxo) = inp. witness_utxo {
105- script_pubkey = & witness_utxo. script_pubkey ;
106- } else if let Some ( ref non_witness_utxo) = inp. non_witness_utxo {
107- let vout = psbt. unsigned_tx . input [ index] . previous_output . vout ;
108- script_pubkey = & non_witness_utxo. output [ vout as usize ] . script_pubkey ;
109- } else {
110- return Err ( InputError :: MissingUtxo ) ;
111- }
112- Ok ( script_pubkey)
101+ get_utxo ( psbt, index) . map ( |utxo| & utxo. script_pubkey )
113102}
114103
115- // Get the amount being spent for the psbt input
116- fn get_amt ( psbt : & Psbt , index : usize ) -> Result < u64 , InputError > {
117- let amt;
104+ // Get the spending utxo for this psbt input
105+ fn get_utxo ( psbt : & Psbt , index : usize ) -> Result < & bitcoin:: TxOut , InputError > {
118106 let inp = & psbt. inputs [ index] ;
119- if let Some ( ref witness_utxo) = inp. witness_utxo {
120- amt = witness_utxo. value ;
107+ let utxo = if let Some ( ref witness_utxo) = inp. witness_utxo {
108+ & witness_utxo
121109 } else if let Some ( ref non_witness_utxo) = inp. non_witness_utxo {
122110 let vout = psbt. unsigned_tx . input [ index] . previous_output . vout ;
123- amt = non_witness_utxo. output [ vout as usize ] . value ;
111+ & non_witness_utxo. output [ vout as usize ]
124112 } else {
125113 return Err ( InputError :: MissingUtxo ) ;
114+ } ;
115+ Ok ( utxo)
116+ }
117+
118+ /// Get the Prevouts for the psbt
119+ fn prevouts < ' a > ( psbt : & ' a Psbt ) -> Result < Vec < bitcoin:: TxOut > , super :: Error > {
120+ let mut utxos = vec ! [ ] ;
121+ for i in 0 ..psbt. inputs . len ( ) {
122+ let utxo_ref = get_utxo ( psbt, i) . map_err ( |e| Error :: InputError ( e, i) ) ?;
123+ utxos. push ( utxo_ref. clone ( ) ) ; // RC fix would allow references here instead of clone
126124 }
127- Ok ( amt )
125+ Ok ( utxos )
128126}
129127
130128// Create a descriptor from unfinalized PSBT input.
@@ -284,6 +282,8 @@ pub fn interpreter_check<C: secp256k1::Verification>(
284282 psbt : & Psbt ,
285283 secp : & Secp256k1 < C > ,
286284) -> Result < ( ) , Error > {
285+ let utxos = prevouts ( & psbt) ?;
286+ let utxos = & Prevouts :: All ( & utxos) ;
287287 for ( index, input) in psbt. inputs . iter ( ) . enumerate ( ) {
288288 let spk = get_scriptpubkey ( psbt, index) . map_err ( |e| Error :: InputError ( e, index) ) ?;
289289 let empty_script_sig = Script :: new ( ) ;
@@ -297,23 +297,14 @@ pub fn interpreter_check<C: secp256k1::Verification>(
297297
298298 // Now look at all the satisfied constraints. If everything is filled in
299299 // corrected, there should be no errors
300-
301- let cltv = psbt. unsigned_tx . lock_time ;
302- let csv = psbt. unsigned_tx . input [ index] . sequence ;
303- let _amt = get_amt ( psbt, index) . map_err ( |e| Error :: InputError ( e, index) ) ?;
304- // let vfyfn = interpreter
305- // .sighash_verify(&secp, &psbt.unsigned_tx, index, amt)
306- // .map_err(|e| Error::InputError(InputError::Interpreter(e), index))?;
307- // Will change in later commmit
300+ // Interpreter check
308301 {
302+ let cltv = psbt. unsigned_tx . lock_time ;
303+ let csv = psbt. unsigned_tx . input [ index] . sequence ;
309304 let interpreter =
310305 interpreter:: Interpreter :: from_txdata ( spk, & script_sig, & witness, cltv, csv)
311306 . map_err ( |e| Error :: InputError ( InputError :: Interpreter ( e) , index) ) ?;
312- let y = |_x : & KeySigPair | {
313- secp. ctx ( ) ;
314- true
315- } ;
316- let iter = interpreter. iter_custom ( Box :: new ( y) ) ;
307+ let iter = interpreter. iter ( secp, & psbt. unsigned_tx , index, & utxos) ;
317308 if let Some ( error) = iter. filter_map ( Result :: err) . next ( ) {
318309 return Err ( Error :: InputError ( InputError :: Interpreter ( error) , index) ) ;
319310 } ;
0 commit comments