|
8 | 8 | use core::fmt; |
9 | 9 |
|
10 | 10 | use super::{TxOut, TxOutWitness}; |
11 | | -use crate::encoding::{Decoder4, Decoder4Error}; |
| 11 | +use crate::encoding::{ |
| 12 | + Decode, Decoder, Decoder2, Decoder2Error, Decoder4, Decoder4Error, DecoderStatus, |
| 13 | +}; |
| 14 | + |
| 15 | +decoder_newtype! { |
| 16 | + /// Decoder for the [`TxOutWitness`] type. |
| 17 | + #[derive(Default)] |
| 18 | + pub struct TxOutWitnessDecoder(Decoder2< |
| 19 | + crate::confidential::SurjectionProofDecoder, |
| 20 | + crate::confidential::RangeProofDecoder, |
| 21 | + >); |
| 22 | + |
| 23 | + /// Decoder error for the [`TxOutWitness`] type. |
| 24 | + #[derive(Clone, PartialEq, Eq, Debug)] |
| 25 | + pub struct TxOutWitnessDecoderError(Decoder2Error< |
| 26 | + crate::confidential::SurjectionProofDecoderError, |
| 27 | + crate::confidential::RangeProofDecoderError, |
| 28 | + >); |
| 29 | + const ERROR_DISPLAY = "error decoding transaction output witness"; |
| 30 | + |
| 31 | + impl Decode for TxOutWitness { |
| 32 | + fn convert_inner(output) -> Result<_, TxOutWitnessDecoderErrorInner> { |
| 33 | + let (surjection_proof, rangeproof) = output; |
| 34 | + Ok(TxOutWitness {surjection_proof, rangeproof }) |
| 35 | + } |
| 36 | + } |
| 37 | +} |
| 38 | + |
| 39 | +/// An decoder for the witnesses in a sequence of [`TxOut`]s. |
| 40 | +/// |
| 41 | +/// Comsumes a vec of [`TxOut`]s on construction and then yields that |
| 42 | +/// same vector, with the witness fields overwritten. |
| 43 | +#[derive(Default)] |
| 44 | +struct TxOutWitnessesDecoder { |
| 45 | + txouts: Vec<TxOut>, |
| 46 | + index: usize, |
| 47 | + // Invariant: if this is Some then |
| 48 | + decoder: Option<TxOutWitnessDecoder>, |
| 49 | +} |
| 50 | + |
| 51 | +impl TxOutWitnessesDecoder { |
| 52 | + #[allow(dead_code)] // will be used in the Transaction Encode/Decode commit |
| 53 | + fn new(txouts: Vec<TxOut>) -> Self { Self { txouts, index: 0, decoder: None } } |
| 54 | +} |
| 55 | + |
| 56 | +impl Decoder for TxOutWitnessesDecoder { |
| 57 | + type Output = Vec<TxOut>; |
| 58 | + type Error = TxOutWitnessDecoderError; |
| 59 | + |
| 60 | + fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<DecoderStatus, Self::Error> { |
| 61 | + loop { |
| 62 | + let Some(next_txout) = self.txouts.get_mut(self.index) else { |
| 63 | + return Ok(DecoderStatus::Ready); |
| 64 | + }; |
| 65 | + |
| 66 | + let mut decoder = self.decoder.take().unwrap_or_else(TxOutWitness::decoder); |
| 67 | + if decoder.push_bytes(bytes)?.needs_more() { |
| 68 | + self.decoder = Some(decoder); |
| 69 | + return Ok(DecoderStatus::NeedsMore); |
| 70 | + } |
| 71 | + next_txout.witness = decoder.end()?; |
| 72 | + self.index += 1; |
| 73 | + } |
| 74 | + } |
| 75 | + |
| 76 | + fn end(mut self) -> Result<Self::Output, Self::Error> { |
| 77 | + loop { |
| 78 | + let Some(last_txout) = self.txouts.get_mut(self.index) else { |
| 79 | + return Ok(self.txouts); |
| 80 | + }; |
| 81 | + |
| 82 | + last_txout.witness = self.decoder.take().unwrap_or_else(TxOutWitness::decoder).end()?; |
| 83 | + self.index += 1; |
| 84 | + } |
| 85 | + } |
| 86 | + |
| 87 | + fn read_limit(&self) -> usize { |
| 88 | + self.decoder.as_ref().map_or(0, TxOutWitnessDecoder::read_limit) |
| 89 | + } |
| 90 | +} |
12 | 91 |
|
13 | 92 | decoder_newtype! { |
14 | 93 | /// Decoder for the [`TxOut`] type. |
|
0 commit comments