@@ -35,7 +35,7 @@ pub(crate) trait PsbtExt: Sized {
35
35
) -> & mut BTreeMap < bip32:: Xpub , ( bip32:: Fingerprint , bip32:: DerivationPath ) > ;
36
36
fn proprietary_mut ( & mut self ) -> & mut BTreeMap < psbt:: raw:: ProprietaryKey , Vec < u8 > > ;
37
37
fn unknown_mut ( & mut self ) -> & mut BTreeMap < psbt:: raw:: Key , Vec < u8 > > ;
38
- fn input_pairs ( & self ) -> Box < dyn Iterator < Item = InputPair < ' _ > > + ' _ > ;
38
+ fn input_pairs ( & self ) -> Box < dyn Iterator < Item = InternalInputPair < ' _ > > + ' _ > ;
39
39
// guarantees that length of psbt input matches that of unsigned_tx inputs and same
40
40
/// thing for outputs.
41
41
fn validate ( self ) -> Result < Self , InconsistentPsbt > ;
@@ -59,13 +59,13 @@ impl PsbtExt for Psbt {
59
59
60
60
fn unknown_mut ( & mut self ) -> & mut BTreeMap < psbt:: raw:: Key , Vec < u8 > > { & mut self . unknown }
61
61
62
- fn input_pairs ( & self ) -> Box < dyn Iterator < Item = InputPair < ' _ > > + ' _ > {
62
+ fn input_pairs ( & self ) -> Box < dyn Iterator < Item = InternalInputPair < ' _ > > + ' _ > {
63
63
Box :: new (
64
64
self . unsigned_tx
65
65
. input
66
66
. iter ( )
67
67
. zip ( & self . inputs )
68
- . map ( |( txin, psbtin) | InputPair { txin, psbtin } ) ,
68
+ . map ( |( txin, psbtin) | InternalInputPair { txin, psbtin } ) ,
69
69
)
70
70
}
71
71
@@ -106,12 +106,13 @@ fn redeem_script(script_sig: &Script) -> Option<&Script> {
106
106
// https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#p2wpkh-nested-in-bip16-p2sh
107
107
const NESTED_P2WPKH_MAX : InputWeightPrediction = InputWeightPrediction :: from_slice ( 23 , & [ 72 , 33 ] ) ;
108
108
109
- pub ( crate ) struct InputPair < ' a > {
109
+ #[ derive( Clone , Debug ) ]
110
+ pub ( crate ) struct InternalInputPair < ' a > {
110
111
pub txin : & ' a TxIn ,
111
112
pub psbtin : & ' a psbt:: Input ,
112
113
}
113
114
114
- impl < ' a > InputPair < ' a > {
115
+ impl < ' a > InternalInputPair < ' a > {
115
116
/// Returns TxOut associated with the input
116
117
pub fn previous_txout ( & self ) -> Result < & TxOut , PrevTxOutError > {
117
118
match ( & self . psbtin . non_witness_utxo , & self . psbtin . witness_utxo ) {
@@ -132,10 +133,13 @@ impl<'a> InputPair<'a> {
132
133
}
133
134
}
134
135
135
- pub fn validate_utxo ( & self , treat_missing_as_error : bool ) -> Result < ( ) , PsbtInputError > {
136
+ pub fn validate_utxo (
137
+ & self ,
138
+ treat_missing_as_error : bool ,
139
+ ) -> Result < ( ) , InternalPsbtInputError > {
136
140
match ( & self . psbtin . non_witness_utxo , & self . psbtin . witness_utxo ) {
137
141
( None , None ) if treat_missing_as_error =>
138
- Err ( PsbtInputError :: PrevTxOut ( PrevTxOutError :: MissingUtxoInformation ) ) ,
142
+ Err ( InternalPsbtInputError :: PrevTxOut ( PrevTxOutError :: MissingUtxoInformation ) ) ,
139
143
( None , None ) => Ok ( ( ) ) ,
140
144
( Some ( tx) , None ) if tx. compute_txid ( ) == self . txin . previous_output . txid => tx
141
145
. output
@@ -153,7 +157,7 @@ impl<'a> InputPair<'a> {
153
157
. into ( )
154
158
} )
155
159
. map ( drop) ,
156
- ( Some ( _) , None ) => Err ( PsbtInputError :: UnequalTxid ) ,
160
+ ( Some ( _) , None ) => Err ( InternalPsbtInputError :: UnequalTxid ) ,
157
161
( None , Some ( _) ) => Ok ( ( ) ) ,
158
162
( Some ( tx) , Some ( witness_txout) )
159
163
if tx. compute_txid ( ) == self . txin . previous_output . txid =>
@@ -173,10 +177,10 @@ impl<'a> InputPair<'a> {
173
177
if witness_txout == non_witness_txout {
174
178
Ok ( ( ) )
175
179
} else {
176
- Err ( PsbtInputError :: SegWitTxOutMismatch )
180
+ Err ( InternalPsbtInputError :: SegWitTxOutMismatch )
177
181
}
178
182
}
179
- ( Some ( _) , Some ( _) ) => Err ( PsbtInputError :: UnequalTxid ) ,
183
+ ( Some ( _) , Some ( _) ) => Err ( InternalPsbtInputError :: UnequalTxid ) ,
180
184
}
181
185
}
182
186
@@ -245,41 +249,66 @@ impl fmt::Display for PrevTxOutError {
245
249
impl std:: error:: Error for PrevTxOutError { }
246
250
247
251
#[ derive( Debug ) ]
248
- pub ( crate ) enum PsbtInputError {
252
+ pub ( crate ) enum InternalPsbtInputError {
249
253
PrevTxOut ( PrevTxOutError ) ,
250
254
UnequalTxid ,
251
255
/// TxOut provided in `segwit_utxo` doesn't match the one in `non_segwit_utxo`
252
256
SegWitTxOutMismatch ,
257
+ AddressType ( AddressTypeError ) ,
258
+ NoRedeemScript ,
253
259
}
254
260
255
- impl fmt:: Display for PsbtInputError {
261
+ impl fmt:: Display for InternalPsbtInputError {
256
262
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
257
263
match self {
258
- PsbtInputError :: PrevTxOut ( _) => write ! ( f, "invalid previous transaction output" ) ,
259
- PsbtInputError :: UnequalTxid => write ! ( f, "transaction ID of previous transaction doesn't match one specified in input spending it" ) ,
260
- PsbtInputError :: SegWitTxOutMismatch => write ! ( f, "transaction output provided in SegWit UTXO field doesn't match the one in non-SegWit UTXO field" ) ,
264
+ Self :: PrevTxOut ( _) => write ! ( f, "invalid previous transaction output" ) ,
265
+ Self :: UnequalTxid => write ! ( f, "transaction ID of previous transaction doesn't match one specified in input spending it" ) ,
266
+ Self :: SegWitTxOutMismatch => write ! ( f, "transaction output provided in SegWit UTXO field doesn't match the one in non-SegWit UTXO field" ) ,
267
+ Self :: AddressType ( _) => write ! ( f, "invalid address type" ) ,
268
+ Self :: NoRedeemScript => write ! ( f, "provided p2sh PSBT input is missing a redeem_script" ) ,
261
269
}
262
270
}
263
271
}
264
272
265
- impl std:: error:: Error for PsbtInputError {
273
+ impl std:: error:: Error for InternalPsbtInputError {
266
274
fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > {
267
275
match self {
268
- PsbtInputError :: PrevTxOut ( error) => Some ( error) ,
269
- PsbtInputError :: UnequalTxid => None ,
270
- PsbtInputError :: SegWitTxOutMismatch => None ,
276
+ Self :: PrevTxOut ( error) => Some ( error) ,
277
+ Self :: UnequalTxid => None ,
278
+ Self :: SegWitTxOutMismatch => None ,
279
+ Self :: AddressType ( error) => Some ( error) ,
280
+ Self :: NoRedeemScript => None ,
271
281
}
272
282
}
273
283
}
274
284
275
- impl From < PrevTxOutError > for PsbtInputError {
276
- fn from ( value : PrevTxOutError ) -> Self { PsbtInputError :: PrevTxOut ( value) }
285
+ impl From < PrevTxOutError > for InternalPsbtInputError {
286
+ fn from ( value : PrevTxOutError ) -> Self { InternalPsbtInputError :: PrevTxOut ( value) }
287
+ }
288
+
289
+ impl From < AddressTypeError > for InternalPsbtInputError {
290
+ fn from ( value : AddressTypeError ) -> Self { Self :: AddressType ( value) }
291
+ }
292
+
293
+ #[ derive( Debug ) ]
294
+ pub struct PsbtInputError ( InternalPsbtInputError ) ;
295
+
296
+ impl From < InternalPsbtInputError > for PsbtInputError {
297
+ fn from ( e : InternalPsbtInputError ) -> Self { PsbtInputError ( e) }
298
+ }
299
+
300
+ impl fmt:: Display for PsbtInputError {
301
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result { write ! ( f, "{}" , self . 0 ) }
302
+ }
303
+
304
+ impl std:: error:: Error for PsbtInputError {
305
+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > { Some ( & self . 0 ) }
277
306
}
278
307
279
308
#[ derive( Debug ) ]
280
309
pub struct PsbtInputsError {
281
310
index : usize ,
282
- error : PsbtInputError ,
311
+ error : InternalPsbtInputError ,
283
312
}
284
313
285
314
impl fmt:: Display for PsbtInputsError {
0 commit comments