Skip to main content

bitcoin_consensus_encoding/decode/
mod.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Consensus Decoding Traits
4
5pub mod decoders;
6
7#[cfg(feature = "hex")]
8use crate::error::{FromHexError, FromHexErrorInner};
9#[cfg(feature = "std")]
10use crate::ReadError;
11use crate::{DecodeError, UnconsumedError};
12
13/// A Bitcoin object which can be consensus-decoded using a push decoder.
14///
15/// To decode something, create a [`Self::Decoder`] and push byte slices into it with
16/// [`Decoder::push_bytes`], then call [`Decoder::end`] to get the result.
17///
18/// # Examples
19///
20/// ```
21/// use bitcoin_consensus_encoding::{decode_from_slice, Decode, Decoder, DecoderStatus, ArrayDecoder, UnexpectedEofError};
22///
23/// struct Foo([u8; 4]);
24///
25/// #[derive(Default)]
26/// struct FooDecoder(ArrayDecoder<4>);
27///
28/// impl Decoder for FooDecoder {
29///     type Output = Foo;
30///     type Error = UnexpectedEofError;
31///
32///     fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<DecoderStatus, Self::Error> {
33///         self.0.push_bytes(bytes)
34///     }
35///     fn end(self) -> Result<Self::Output, Self::Error> { self.0.end().map(Foo) }
36///     fn read_limit(&self) -> usize { self.0.read_limit() }
37/// }
38///
39/// impl Decode for Foo {
40///     type Decoder = FooDecoder;
41/// }
42///
43/// let foo: Foo = decode_from_slice(&[0xde, 0xad, 0xbe, 0xef]).unwrap();
44/// assert_eq!(foo.0, [0xde, 0xad, 0xbe, 0xef]);
45/// ```
46pub trait Decode {
47    /// Associated decoder for the type.
48    type Decoder: Decoder<Output = Self> + Default;
49
50    /// Constructs a "default decoder" for the type.
51    fn decoder() -> Self::Decoder { Self::Decoder::default() }
52}
53
54/// A push decoder for a consensus-decodable object.
55pub trait Decoder: Sized {
56    /// The type that this decoder produces when decoding is complete.
57    type Output;
58    /// The error type that this decoder can produce.
59    type Error;
60
61    /// Pushes bytes into the decoder, consuming as much as possible.
62    ///
63    /// The slice reference will be advanced to point to the unconsumed portion. Returns
64    /// `Ok(DecoderStatus::NeedsMore)` if more bytes are needed to complete decoding,
65    /// `Ok(DecoderStatus::Ready)` if the decoder is ready to finalize with [`Self::end`], or
66    /// `Err(error)` if parsing failed.
67    ///
68    /// Once the decoder returns `Ok(DecoderStatus::Ready)`, subsequent calls to this method will
69    /// continue to return `Ok(DecoderStatus::Ready)` without consuming additional bytes.
70    ///
71    /// # Errors
72    ///
73    /// Returns an error if the provided bytes are invalid or malformed according to the decoder's
74    /// validation rules. Insufficient data (needing more bytes) is *not* an error for this method,
75    /// the decoder will simply consume what it can and return `DecoderStatus::NeedsMore` to
76    /// indicate more data is needed.
77    ///
78    /// # Panics
79    ///
80    /// May panic if called after a previous call to [`Self::push_bytes`] errored.
81    #[must_use = "must check result to avoid panics on subsequent calls"]
82    #[track_caller]
83    fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<DecoderStatus, Self::Error>;
84
85    /// Completes the decoding process and returns the final result.
86    ///
87    /// This consumes the decoder and should be called when no more input data is available.
88    ///
89    /// # Errors
90    ///
91    /// Returns an error if the decoder has not received sufficient data to complete decoding, or if
92    /// the accumulated data is invalid when considered as a complete object.
93    ///
94    /// # Panics
95    ///
96    /// May panic if called after a previous call to [`Self::push_bytes`] errored.
97    #[must_use = "must check result to avoid panics on subsequent calls"]
98    #[track_caller]
99    fn end(self) -> Result<Self::Output, Self::Error>;
100
101    /// Returns the maximum number of bytes this decoder can consume without over-reading.
102    ///
103    /// Returns 0 if the decoder is complete and ready to finalize with [`Self::end`]. This is used
104    /// by [`decode_from_read_unbuffered`] to optimize read sizes, avoiding both inefficient
105    /// under-reads and unnecessary over-reads.
106    fn read_limit(&self) -> usize;
107}
108
109/// Indicates whether a decoder needs more data or is ready to finalize.
110///
111/// This is returned from the [`Decoder::push_bytes`] method to indicate whether the decoder
112/// should continue accumulating data or is ready to produce the decoded value with [`Decoder::end`].
113#[derive(Debug, Copy, Clone, Eq, PartialEq)]
114pub enum DecoderStatus {
115    /// The decoder needs more data to complete decoding.
116    ///
117    /// Continue pushing byte slices with [`Decoder::push_bytes`] until this status changes to
118    /// [`Ready`](DecoderStatus::Ready).
119    NeedsMore,
120
121    /// The decoder has accumulated sufficient data and is ready to finalize.
122    ///
123    /// Call [`Decoder::end`] to complete the decoding process and obtain the final result.
124    Ready,
125}
126
127impl DecoderStatus {
128    /// Returns `true` if the decoder needs more data to continue.
129    pub fn needs_more(&self) -> bool { matches!(self, Self::NeedsMore) }
130
131    /// Returns `true` if ready to produce decoded value with [`Decoder::end`].
132    pub fn is_ready(&self) -> bool { matches!(self, Self::Ready) }
133}
134
135/// Decodes an object from a hex string without heap allocations.
136///
137/// # Errors
138///
139/// [`FromHexError`] if the string has an odd number of characters, any character is not a
140/// valid hex digit, or if decoding the type fails, including if bytes remain unconsumed
141/// after the decoder completes.
142#[cfg(feature = "hex")]
143pub fn decode_from_hex<T: Decode>(
144    hex: &str,
145) -> Result<T, FromHexError<<T::Decoder as Decoder>::Error>> {
146    decode_from_hex_internal(hex, T::decoder())
147}
148
149/// Decodes an object from a hex string without heap allocations using a [`Decoder`] type.
150///
151/// Unlike [`decode_from_hex`], this takes a generic [`Decoder`] parameter, allowing use with
152/// decoders which don't have a dedicated [`Decode`] implementer (e.g. [`CompactSizeDecoder`]).
153///
154/// # Errors
155///
156/// [`FromHexError`] if the string has an odd number of characters, any character is not a
157/// valid hex digit, or if decoding the type fails, including if bytes remain unconsumed
158/// after the decoder completes.
159///
160/// [`CompactSizeDecoder`]: crate::CompactSizeDecoder
161#[cfg(feature = "hex")]
162pub fn decode_from_hex_with_decoder<D: Decoder + Default>(
163    hex: &str,
164) -> Result<D::Output, FromHexError<D::Error>> {
165    decode_from_hex_internal(hex, D::default())
166}
167
168#[cfg(feature = "hex")]
169fn decode_from_hex_internal<D: Decoder>(
170    hex: &str,
171    mut decoder: D,
172) -> Result<D::Output, FromHexError<D::Error>> {
173    let iter = hex::HexSliceToBytesIter::new(hex)
174        .map_err(FromHexErrorInner::OddLength)
175        .map_err(FromHexError)?;
176
177    let mut buffer = [0u8; 4096];
178    let mut index = 0;
179
180    for item in iter {
181        let byte = item.map_err(FromHexErrorInner::InvalidChar).map_err(FromHexError)?;
182
183        if index == buffer.len() {
184            let mut to_flush = buffer.as_slice();
185            // There is at least a single byte left after flushing the buffer. Error if the decoder
186            // is ready after flush.
187            while !to_flush.is_empty() {
188                if decoder
189                    .push_bytes(&mut to_flush)
190                    .map_err(|e| FromHexError(FromHexErrorInner::Decode(DecodeError::Parse(e))))?
191                    .is_ready()
192                {
193                    return Err(FromHexError(FromHexErrorInner::Decode(DecodeError::Unconsumed(
194                        UnconsumedError(),
195                    ))));
196                }
197            }
198            index = 0;
199        }
200        buffer[index] = byte;
201        index += 1;
202    }
203
204    let mut to_flush = &buffer[..index];
205    while !to_flush.is_empty() {
206        if decoder
207            .push_bytes(&mut to_flush)
208            .map_err(|e| FromHexError(FromHexErrorInner::Decode(DecodeError::Parse(e))))?
209            .is_ready()
210        {
211            break;
212        }
213    }
214
215    if to_flush.is_empty() {
216        decoder.end().map_err(|e| FromHexError(FromHexErrorInner::Decode(DecodeError::Parse(e))))
217    } else {
218        Err(FromHexError(FromHexErrorInner::Decode(DecodeError::Unconsumed(UnconsumedError()))))
219    }
220}
221
222/// Decodes an object from a byte slice.
223///
224/// # Errors
225///
226/// Returns an error if the decoder encounters an error while parsing the data, including
227/// insufficient data. This function also errors if the provided slice is not completely consumed
228/// during decode.
229pub fn decode_from_slice<T: Decode>(
230    bytes: &[u8],
231) -> Result<T, DecodeError<<T::Decoder as Decoder>::Error>> {
232    decode_from_slice_internal(bytes, T::decoder())
233}
234
235/// Decodes an object from a byte slice using a [`Decoder`] type.
236///
237/// Unlike [`decode_from_slice`], this takes a generic [`Decoder`] parameter, allowing use with
238/// decoders which don't have a dedicated [`Decode`] implementer (e.g. [`CompactSizeDecoder`]).
239///
240/// # Errors
241///
242/// Returns an error if the decoder encounters an error while parsing the data, including
243/// insufficient data. This function also errors if the provided slice is not completely consumed
244/// during decode.
245///
246/// [`CompactSizeDecoder`]: crate::CompactSizeDecoder
247pub fn decode_from_slice_with_decoder<D: Decoder + Default>(
248    bytes: &[u8],
249) -> Result<D::Output, DecodeError<D::Error>> {
250    decode_from_slice_internal(bytes, D::default())
251}
252
253fn decode_from_slice_internal<D: Decoder>(
254    bytes: &[u8],
255    decoder: D,
256) -> Result<D::Output, DecodeError<D::Error>> {
257    let mut remaining = bytes;
258    let data = decode_from_slice_unbounded_internal(&mut remaining, decoder)
259        .map_err(DecodeError::Parse)?;
260
261    if remaining.is_empty() {
262        Ok(data)
263    } else {
264        Err(DecodeError::Unconsumed(UnconsumedError()))
265    }
266}
267
268/// Decodes an object from an unbounded byte slice.
269///
270/// Unlike [`decode_from_slice`], this function will not error if the slice contains additional
271/// bytes that are not required to decode. Furthermore, the byte slice reference provided to this
272/// function will be updated based on the consumed data, returning the unconsumed bytes.
273///
274/// # Errors
275///
276/// Returns an error if the decoder encounters an error while parsing the data, including
277/// insufficient data.
278pub fn decode_from_slice_unbounded<T>(
279    bytes: &mut &[u8],
280) -> Result<T, <T::Decoder as Decoder>::Error>
281where
282    T: Decode,
283{
284    decode_from_slice_unbounded_internal(bytes, T::decoder())
285}
286
287/// Decodes an object from an unbounded byte slice using a [`Decoder`] type.
288///
289/// Unlike [`decode_from_slice_unbounded`], this takes a generic [`Decoder`] parameter, allowing
290/// use with decoders which don't have a dedicated [`Decode`] implementer
291/// (e.g. [`CompactSizeDecoder`]).
292///
293/// Unlike [`decode_from_slice_with_decoder`], this function will not error if the slice contains
294/// additional bytes that are not required to decode. Furthermore, the byte slice reference provided
295/// to this function will be updated based on the consumed data, returning the unconsumed bytes.
296///
297/// # Errors
298///
299/// Returns an error if the decoder encounters an error while parsing the data, including
300/// insufficient data.
301///
302/// [`CompactSizeDecoder`]: crate::CompactSizeDecoder
303pub fn decode_from_slice_unbounded_with_decoder<D: Decoder + Default>(
304    bytes: &mut &[u8],
305) -> Result<D::Output, D::Error> {
306    decode_from_slice_unbounded_internal(bytes, D::default())
307}
308
309fn decode_from_slice_unbounded_internal<D: Decoder>(
310    bytes: &mut &[u8],
311    mut decoder: D,
312) -> Result<D::Output, D::Error> {
313    while !bytes.is_empty() {
314        if decoder.push_bytes(bytes)?.is_ready() {
315            break;
316        }
317    }
318
319    decoder.end()
320}
321
322/// Decodes an object from a buffered reader.
323///
324/// # Performance
325///
326/// For unbuffered readers (like [`std::fs::File`] or [`std::net::TcpStream`]), consider wrapping
327/// your reader with [`std::io::BufReader`] in order to use this function. This avoids frequent
328/// small reads, which can significantly impact performance.
329///
330/// # Errors
331///
332/// Returns [`ReadError::Decode`] if the decoder encounters an error while parsing the data, or
333/// [`ReadError::Io`] if an I/O error occurs while reading.
334#[cfg(feature = "std")]
335pub fn decode_from_read<T, R>(reader: R) -> Result<T, ReadError<<T::Decoder as Decoder>::Error>>
336where
337    T: Decode,
338    R: std::io::BufRead,
339{
340    decode_from_read_internal::<T::Decoder, R>(reader, T::decoder())
341}
342
343/// Decodes an object from a buffered reader using a [`Decoder`] type.
344///
345/// Unlike [`decode_from_read`], this takes a generic [`Decoder`] parameter, allowing use with
346/// decoders which don't have a dedicated [`Decode`] implementer (e.g. [`CompactSizeDecoder`]).
347///
348/// # Performance
349///
350/// For unbuffered readers (like [`std::fs::File`] or [`std::net::TcpStream`]), consider wrapping
351/// your reader with [`std::io::BufReader`] in order to use this function. This avoids frequent
352/// small reads, which can significantly impact performance.
353///
354/// # Errors
355///
356/// Returns [`ReadError::Decode`] if the decoder encounters an error while parsing the data, or
357/// [`ReadError::Io`] if an I/O error occurs while reading.
358///
359/// [`CompactSizeDecoder`]: crate::CompactSizeDecoder
360#[cfg(feature = "std")]
361pub fn decode_from_read_with_decoder<D, R>(reader: R) -> Result<D::Output, ReadError<D::Error>>
362where
363    D: Decoder + Default,
364    R: std::io::BufRead,
365{
366    decode_from_read_internal(reader, D::default())
367}
368
369#[cfg(feature = "std")]
370fn decode_from_read_internal<D, R>(
371    mut reader: R,
372    mut decoder: D,
373) -> Result<D::Output, ReadError<D::Error>>
374where
375    D: Decoder,
376    R: std::io::BufRead,
377{
378    loop {
379        let mut buffer = match reader.fill_buf() {
380            Ok(buffer) => buffer,
381            // Auto retry read for non-fatal error.
382            Err(error) if error.kind() == std::io::ErrorKind::Interrupted => continue,
383            Err(error) => return Err(ReadError::Io(error)),
384        };
385
386        if buffer.is_empty() {
387            // EOF, but still try to finalize the decoder.
388            return decoder.end().map_err(ReadError::Decode);
389        }
390
391        let original_len = buffer.len();
392        let status = decoder.push_bytes(&mut buffer).map_err(ReadError::Decode)?;
393        let consumed = original_len - buffer.len();
394        reader.consume(consumed);
395
396        if status.is_ready() {
397            return decoder.end().map_err(ReadError::Decode);
398        }
399    }
400}
401
402/// Decodes an object from an unbuffered reader using a fixed-size buffer.
403///
404/// For most use cases, prefer [`decode_from_read`] with a [`std::io::BufReader`]. This function is
405/// only needed when you have an unbuffered reader which you cannot wrap. It will probably have
406/// worse performance.
407///
408/// # Buffer
409///
410/// Uses a fixed 4KB (4096 bytes) stack-allocated buffer that is reused across read operations. This
411/// size is a good balance between memory usage and system call efficiency for most use cases.
412///
413/// For different buffer sizes, use [`decode_from_read_unbuffered_with`].
414///
415/// # Errors
416///
417/// Returns [`ReadError::Decode`] if the decoder encounters an error while parsing the data, or
418/// [`ReadError::Io`] if an I/O error occurs while reading.
419#[cfg(feature = "std")]
420pub fn decode_from_read_unbuffered<T, R>(
421    reader: R,
422) -> Result<T, ReadError<<T::Decoder as Decoder>::Error>>
423where
424    T: Decode,
425    R: std::io::Read,
426{
427    decode_from_read_unbuffered_with::<T, R, 4096>(reader)
428}
429
430/// Decodes an object from an unbuffered reader using a custom-sized buffer.
431///
432/// For most use cases, prefer [`decode_from_read`] with a [`std::io::BufReader`]. This function is
433/// only needed when you have an unbuffered reader which you cannot wrap. It will probably have
434/// worse performance.
435///
436/// # Buffer
437///
438/// The `BUFFER_SIZE` parameter controls the intermediate buffer size used for reading. The buffer
439/// is allocated on the stack (not heap) and reused across read operations. Larger buffers reduce
440/// the number of system calls, but use more memory.
441///
442/// # Errors
443///
444/// Returns [`ReadError::Decode`] if the decoder encounters an error while parsing the data, or
445/// [`ReadError::Io`] if an I/O error occurs while reading.
446#[cfg(feature = "std")]
447pub fn decode_from_read_unbuffered_with<T, R, const BUFFER_SIZE: usize>(
448    mut reader: R,
449) -> Result<T, ReadError<<T::Decoder as Decoder>::Error>>
450where
451    T: Decode,
452    R: std::io::Read,
453{
454    let mut decoder = T::decoder();
455    let mut buffer = [0u8; BUFFER_SIZE];
456
457    while decoder.read_limit() > 0 {
458        // Only read what we need, up to buffer size.
459        let clamped_buffer = &mut buffer[..decoder.read_limit().min(BUFFER_SIZE)];
460        match reader.read(clamped_buffer) {
461            Ok(0) => {
462                // EOF, but still try to finalize the decoder.
463                return decoder.end().map_err(ReadError::Decode);
464            }
465            Ok(bytes_read) => {
466                let mut to_push = &clamped_buffer[..bytes_read];
467                while !to_push.is_empty() {
468                    if decoder.push_bytes(&mut to_push).map_err(ReadError::Decode)?.is_ready() {
469                        return decoder.end().map_err(ReadError::Decode);
470                    }
471                }
472            }
473            Err(ref e) if e.kind() == std::io::ErrorKind::Interrupted => {
474                // Auto retry read for non-fatal error.
475            }
476            Err(e) => return Err(ReadError::Io(e)),
477        }
478    }
479
480    decoder.end().map_err(ReadError::Decode)
481}
482
483/// Checks that the given bytes decode to the expected value, panicking if they don't.
484///
485/// This is intended for tests only.
486///
487/// # Panics
488///
489/// If the decoded value doesn't match the expected value, or if decoding fails.
490#[track_caller]
491pub fn check_decode<T: Decode + Eq + core::fmt::Debug>(bytes: &[u8], expected: &T)
492where
493    <T::Decoder as Decoder>::Error: core::fmt::Debug,
494{
495    let decoder = T::decoder();
496    check_decoder(decoder, bytes, expected);
497}
498
499/// Checks that the given `decoder` produces the expected value, panicking if it doesn't.
500///
501/// This is intended for tests only.
502///
503/// # Panics
504///
505/// If the decoder doesn't produce the expected value or if decoding fails.
506#[track_caller]
507pub fn check_decoder<D: Decoder>(mut decoder: D, mut bytes: &[u8], expected: &D::Output)
508where
509    D::Output: Eq + core::fmt::Debug,
510    D::Error: core::fmt::Debug,
511{
512    loop {
513        match decoder.push_bytes(&mut bytes) {
514            Ok(status) => {
515                if status.is_ready() {
516                    break;
517                }
518                assert!(!bytes.is_empty(), "decoder needs more data but no bytes remaining");
519            }
520            Err(e) => panic!("decoder failed with error: {e:?}"),
521        }
522    }
523
524    match decoder.end() {
525        Ok(result) => {
526            assert_eq!(&result, expected, "decoded value doesn't match expected value");
527        }
528        Err(e) => panic!("decoder finalization failed with error: {e:?}"),
529    }
530}