@@ -10,10 +10,12 @@ use core::fmt;
1010use super :: {
1111 AssetIssuance , OutPoint , Script , Sequence , TxIn , TxInWitness , TxOut , TxOutWitness , Txid ,
1212} ;
13+ use crate :: confidential:: { RangeProofDecoder , RangeProofDecoderError } ;
1314use crate :: encoding:: {
1415 ArrayDecoder , Decode , Decoder , Decoder2 , Decoder2Error , Decoder3 , Decoder4 , Decoder4Error ,
1516 DecoderStatus , UnexpectedEofError ,
1617} ;
18+ use crate :: { PeginWitnessDecoder , PeginWitnessDecoderError , WitnessDecoder , WitnessDecoderError } ;
1719
1820/// Decoder for the [`OutPoint`] type.
1921///
@@ -223,6 +225,113 @@ impl std::error::Error for TxInDecoderError {
223225 }
224226}
225227
228+ /// Decoder for the [`TxInWitness`] type.
229+ #[ derive( Default ) ]
230+ pub struct TxInWitnessDecoder {
231+ inner : Decoder4 < RangeProofDecoder , RangeProofDecoder , WitnessDecoder , PeginWitnessDecoder > ,
232+ }
233+
234+ /// Decoder error for the [`TxInWitness`] type.
235+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
236+ pub struct TxInWitnessDecoderError (
237+ Decoder4Error <
238+ RangeProofDecoderError ,
239+ RangeProofDecoderError ,
240+ WitnessDecoderError ,
241+ PeginWitnessDecoderError ,
242+ > ,
243+ ) ;
244+
245+ impl fmt:: Display for TxInWitnessDecoderError {
246+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
247+ f. write_str ( "error decoding transaction input witness" )
248+ }
249+ }
250+
251+ impl std:: error:: Error for TxInWitnessDecoderError {
252+ fn source ( & self ) -> Option < & ( dyn std:: error:: Error + ' static ) > { Some ( & self . 0 ) }
253+ }
254+
255+ impl Decoder for TxInWitnessDecoder {
256+ type Output = TxInWitness ;
257+ type Error = TxInWitnessDecoderError ;
258+
259+ fn push_bytes ( & mut self , bytes : & mut & [ u8 ] ) -> Result < DecoderStatus , Self :: Error > {
260+ self . inner . push_bytes ( bytes) . map_err ( TxInWitnessDecoderError )
261+ }
262+
263+ fn end ( self ) -> Result < Self :: Output , Self :: Error > {
264+ let ( amount_rangeproof, inflation_keys_rangeproof, script_witness, pegin_witness) =
265+ self . inner . end ( ) . map_err ( TxInWitnessDecoderError ) ?;
266+
267+ Ok ( TxInWitness {
268+ amount_rangeproof,
269+ inflation_keys_rangeproof,
270+ script_witness,
271+ pegin_witness,
272+ } )
273+ }
274+
275+ fn read_limit ( & self ) -> usize { self . inner . read_limit ( ) }
276+ }
277+
278+ impl Decode for TxInWitness {
279+ type Decoder = TxInWitnessDecoder ;
280+ }
281+
282+ /// An decoder for the witnesses in a sequence of [`TxIn`]s.
283+ ///
284+ /// Comsumes a vec of [`TxIn`]s on construction and then yields that
285+ /// same vector, with the witness fields overwritten.
286+ #[ derive( Default ) ]
287+ struct TxInWitnessesDecoder {
288+ txins : Vec < TxIn > ,
289+ index : usize ,
290+ // Invariant: if this is Some then
291+ decoder : Option < TxInWitnessDecoder > ,
292+ }
293+
294+ impl TxInWitnessesDecoder {
295+ #[ allow( dead_code) ] // will be used in the Transaction Encode/Decode commit
296+ fn new ( txins : Vec < TxIn > ) -> Self { Self { txins, index : 0 , decoder : None } }
297+ }
298+
299+ impl Decoder for TxInWitnessesDecoder {
300+ type Output = Vec < TxIn > ;
301+ type Error = TxInWitnessDecoderError ;
302+
303+ fn push_bytes ( & mut self , bytes : & mut & [ u8 ] ) -> Result < DecoderStatus , Self :: Error > {
304+ loop {
305+ let Some ( next_txin) = self . txins . get_mut ( self . index ) else {
306+ return Ok ( DecoderStatus :: Ready ) ;
307+ } ;
308+
309+ let mut decoder = self . decoder . take ( ) . unwrap_or_else ( TxInWitness :: decoder) ;
310+ if decoder. push_bytes ( bytes) ?. needs_more ( ) {
311+ self . decoder = Some ( decoder) ;
312+ return Ok ( DecoderStatus :: NeedsMore ) ;
313+ }
314+ next_txin. witness = decoder. end ( ) ?;
315+ self . index += 1 ;
316+ }
317+ }
318+
319+ fn end ( mut self ) -> Result < Self :: Output , Self :: Error > {
320+ loop {
321+ let Some ( last_txin) = self . txins . get_mut ( self . index ) else {
322+ return Ok ( self . txins ) ;
323+ } ;
324+
325+ last_txin. witness = self . decoder . take ( ) . unwrap_or_else ( TxInWitness :: decoder) . end ( ) ?;
326+ self . index += 1 ;
327+ }
328+ }
329+
330+ fn read_limit ( & self ) -> usize {
331+ self . decoder . as_ref ( ) . map_or ( 0 , TxInWitnessDecoder :: read_limit)
332+ }
333+ }
334+
226335decoder_newtype ! {
227336 /// Decoder for the [`TxOutWitness`] type.
228337 #[ derive( Default ) ]
0 commit comments