19
19
//! `https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki`
20
20
//!
21
21
22
+ use bitcoin:: util:: sighash:: Prevouts ;
22
23
use util:: { script_is_v1_tr, witness_size} ;
23
24
24
- use interpreter:: KeySigPair ;
25
-
26
25
use super :: { sanity_check, Psbt } ;
27
26
use super :: { Error , InputError , PsbtInputSatisfier } ;
28
27
use bitcoin:: blockdata:: witness:: Witness ;
@@ -99,32 +98,31 @@ fn construct_tap_witness(
99
98
100
99
// Get the scriptpubkey for the psbt input
101
100
fn 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 )
113
102
}
114
103
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 > {
118
106
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
121
109
} else if let Some ( ref non_witness_utxo) = inp. non_witness_utxo {
122
110
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 ]
124
112
} else {
125
113
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
126
124
}
127
- Ok ( amt )
125
+ Ok ( utxos )
128
126
}
129
127
130
128
// Create a descriptor from unfinalized PSBT input.
@@ -284,6 +282,8 @@ pub fn interpreter_check<C: secp256k1::Verification>(
284
282
psbt : & Psbt ,
285
283
secp : & Secp256k1 < C > ,
286
284
) -> Result < ( ) , Error > {
285
+ let utxos = prevouts ( & psbt) ?;
286
+ let utxos = & Prevouts :: All ( & utxos) ;
287
287
for ( index, input) in psbt. inputs . iter ( ) . enumerate ( ) {
288
288
let spk = get_scriptpubkey ( psbt, index) . map_err ( |e| Error :: InputError ( e, index) ) ?;
289
289
let empty_script_sig = Script :: new ( ) ;
@@ -297,23 +297,14 @@ pub fn interpreter_check<C: secp256k1::Verification>(
297
297
298
298
// Now look at all the satisfied constraints. If everything is filled in
299
299
// 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
308
301
{
302
+ let cltv = psbt. unsigned_tx . lock_time ;
303
+ let csv = psbt. unsigned_tx . input [ index] . sequence ;
309
304
let interpreter =
310
305
interpreter:: Interpreter :: from_txdata ( spk, & script_sig, & witness, cltv, csv)
311
306
. 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) ;
317
308
if let Some ( error) = iter. filter_map ( Result :: err) . next ( ) {
318
309
return Err ( Error :: InputError ( InputError :: Interpreter ( error) , index) ) ;
319
310
} ;
0 commit comments