serde_bolt/
types.rs

1use crate::take::Take;
2use alloc::boxed::Box;
3use alloc::string::{String, ToString};
4use alloc::vec::Vec;
5use bitcoin::consensus::encode::MAX_VEC_SIZE;
6use bitcoin::consensus::{encode::Error, Decodable, Encodable};
7use bitcoin::io::{self, Read, Write, ErrorKind};
8use chunked_buffer::{GenericChunkedBuffer, IterChunk};
9use core::cmp::min;
10use core::fmt::{Debug, Formatter};
11use core::ops::{Deref, DerefMut};
12
13/// Vec<u8> with nicer debug formatting and u32 big-endian size prefix.
14/// Maximum 65535 bytes, for larger data use `LargeOctets`.
15#[derive(Clone)]
16#[cfg_attr(test, derive(PartialEq))]
17pub struct Octets(pub Vec<u8>);
18
19impl Octets {
20    /// An empty vector
21    pub const EMPTY: Self = Octets(Vec::new());
22}
23
24impl Debug for Octets {
25    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
26        f.write_str(&hex::encode(&self.0))
27    }
28}
29
30impl Deref for Octets {
31    type Target = Vec<u8>;
32    fn deref(&self) -> &Self::Target {
33        &self.0
34    }
35}
36
37impl DerefMut for Octets {
38    fn deref_mut(&mut self) -> &mut Vec<u8> {
39        &mut self.0
40    }
41}
42
43impl From<Vec<u8>> for Octets {
44    fn from(v: Vec<u8>) -> Self {
45        Self(v)
46    }
47}
48
49impl Encodable for Octets {
50    fn consensus_encode<W: Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
51        let len = self.0.len();
52        if len > 0xFFFF {
53            return Err(io::Error::new(
54                io::ErrorKind::InvalidInput,
55                "Octets length exceeds 65535",
56            ));
57        }
58        let mut count = 0;
59        count += (len as u16).to_be_bytes().consensus_encode(writer)?;
60        writer.write_all(&self.0)?;
61        count += len;
62        Ok(count)
63    }
64}
65
66impl Decodable for Octets {
67    fn consensus_decode<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
68        let len = reader.read_u16_be()?;
69        let mut buf = Vec::with_capacity(len as usize);
70        buf.resize(len as usize, 0);
71        reader.read_exact(&mut buf)?;
72        Ok(Octets(buf))
73    }
74}
75
76/// A Vec that implements `Encodable` and `Decodable` as a length-prefixed array,
77/// with a big-endian u16 length prefix.
78#[derive(Clone, Debug)]
79#[cfg_attr(feature = "test_utils", derive(PartialEq))]
80pub struct Array<T: Encodable + Decodable + Debug>(pub Vec<T>);
81
82impl<T: Encodable + Decodable + Debug> Array<T> {
83    /// An empty vector
84    pub fn new() -> Self {
85        Self(Vec::new())
86    }
87}
88
89impl<T: Encodable + Decodable + Debug> Deref for Array<T> {
90    type Target = Vec<T>;
91    fn deref(&self) -> &Self::Target {
92        &self.0
93    }
94}
95
96impl<T: Encodable + Decodable + Debug> DerefMut for Array<T> {
97    fn deref_mut(&mut self) -> &mut Vec<T> {
98        &mut self.0
99    }
100}
101
102impl<T: Encodable + Decodable + Debug> Encodable for Array<T> {
103    fn consensus_encode<W: Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
104        let mut count = 0;
105        count += (self.0.len() as u16)
106            .to_be_bytes()
107            .consensus_encode(writer)?;
108        for item in &self.0 {
109            count += item.consensus_encode(writer)?;
110        }
111        Ok(count)
112    }
113}
114
115impl<T: Encodable + Decodable + Debug> Decodable for Array<T> {
116    fn consensus_decode<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
117        let len = reader.read_u16_be()?;
118        let mut buf = Vec::with_capacity(len as usize);
119        for _ in 0..len {
120            buf.push(Decodable::consensus_decode(reader)?);
121        }
122        Ok(Array(buf))
123    }
124}
125
126impl<T: Encodable + Decodable + Debug> From<Vec<T>> for Array<T> {
127    fn from(v: Vec<T>) -> Self {
128        Self(v)
129    }
130}
131
132/// A Vec that implements `Encodable` and `Decodable` as a length-prefixed array,
133/// with a big-endian u16 length prefix.
134/// Unlike `Array`, this type requires `T` to implement `BigEndianEncodable`.
135/// Mostly useful for things like `ArrayBE<u16>`, where we want the elements
136/// to be encoded as big-endian.
137#[derive(Clone, Debug)]
138pub struct ArrayBE<T: BigEndianEncodable + Debug>(pub Vec<T>);
139
140impl<T: BigEndianEncodable + Debug> ArrayBE<T> {
141    /// An empty vector
142    pub fn new() -> Self {
143        Self(Vec::new())
144    }
145}
146
147impl<T: BigEndianEncodable + Debug> Deref for ArrayBE<T> {
148    type Target = Vec<T>;
149    fn deref(&self) -> &Self::Target {
150        &self.0
151    }
152}
153
154impl<T: BigEndianEncodable + Debug> DerefMut for ArrayBE<T> {
155    fn deref_mut(&mut self) -> &mut Vec<T> {
156        &mut self.0
157    }
158}
159
160impl<T: BigEndianEncodable + Debug> Encodable for ArrayBE<T> {
161    fn consensus_encode<W: Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
162        let mut count = 0;
163        count += (self.0.len() as u16)
164            .to_be_bytes()
165            .consensus_encode(writer)?;
166        for item in &self.0 {
167            count += item.consensus_encode_be(writer).map_err(|e| io::Error::new(ErrorKind::Other, e.to_string()))?;
168        }
169        Ok(count)
170    }
171}
172
173impl<T: BigEndianEncodable + Debug> Decodable for ArrayBE<T> {
174    fn consensus_decode<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
175        let len = reader.read_u16_be()?;
176        let mut buf = Vec::with_capacity(len as usize);
177        for _ in 0..len {
178            buf.push(BigEndianEncodable::consensus_decode_be(reader)?);
179        }
180        Ok(ArrayBE(buf))
181    }
182}
183
184impl<T: BigEndianEncodable + Debug> From<Vec<T>> for ArrayBE<T> {
185    fn from(v: Vec<T>) -> Self {
186        Self(v)
187    }
188}
189
190/// A potentially large vector of bytes, with a u32 big-endian size.
191///
192/// Not used in BOLT-1, because messages are limited to 64 KB.
193#[derive(Clone)]
194#[cfg_attr(test, derive(PartialEq))]
195pub struct LargeOctets(pub Vec<u8>);
196
197impl LargeOctets {
198    /// An empty vector
199    pub const EMPTY: Self = LargeOctets(Vec::new());
200}
201
202impl Debug for LargeOctets {
203    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
204        f.write_str(&hex::encode(&self.0))
205    }
206}
207
208impl Deref for LargeOctets {
209    type Target = Vec<u8>;
210    fn deref(&self) -> &Self::Target {
211        &self.0
212    }
213}
214
215impl DerefMut for LargeOctets {
216    fn deref_mut(&mut self) -> &mut Vec<u8> {
217        &mut self.0
218    }
219}
220
221impl From<Vec<u8>> for LargeOctets {
222    fn from(v: Vec<u8>) -> Self {
223        Self(v)
224    }
225}
226
227impl Encodable for LargeOctets {
228    fn consensus_encode<W: Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
229        let len = self.0.len();
230        let mut count = 0;
231        count += (len as u32).to_be_bytes().consensus_encode(writer)?;
232        writer.write_all(&self.0)?;
233        count += len;
234        Ok(count)
235    }
236}
237
238impl Decodable for LargeOctets {
239    fn consensus_decode<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
240        let len = reader.read_u32_be()?;
241        if len as usize > MAX_VEC_SIZE {
242            return Err(Error::OversizedVectorAllocation {
243                requested: len as usize,
244                max: MAX_VEC_SIZE,
245            });
246        }
247        let mut buf = Vec::with_capacity(len as usize);
248        buf.resize(len as usize, 0);
249        reader.read_exact(&mut buf)?;
250        Ok(LargeOctets(buf))
251    }
252}
253
254/// A potentially large vector of bytes, with a u32 size, that we ignore on deserialize.
255/// On deserialize, the bytes are read and discarded and the inner will be empty.
256#[derive(Clone)]
257#[cfg_attr(test, derive(PartialEq))]
258pub struct IgnoredLargeOctets(pub Vec<u8>);
259
260impl Debug for IgnoredLargeOctets {
261    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
262        f.write_str(&hex::encode(&self.0))
263    }
264}
265
266impl Encodable for IgnoredLargeOctets {
267    fn consensus_encode<W: Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
268        let len = self.0.len();
269        let mut count = 0;
270        count += (len as u32).to_be_bytes().consensus_encode(writer)?;
271        writer.write_all(&self.0)?;
272        count += len;
273        Ok(count)
274    }
275}
276
277impl Decodable for IgnoredLargeOctets {
278    fn consensus_decode<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
279        let mut len = reader.read_u32_be()?;
280        while len > 0 {
281            let mut buf = [0; 1024];
282            let read = reader.read(&mut buf[..min(len as usize, 1024)])?;
283            len -= read as u32;
284        }
285        Ok(IgnoredLargeOctets(Vec::new()))
286    }
287}
288
289/// A variable length zero terminated byte string
290#[derive(Clone)]
291#[cfg_attr(any(test, feature = "test_utils"), derive(PartialEq, Eq))]
292pub struct WireString(pub Vec<u8>);
293
294impl Debug for WireString {
295    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
296        match String::from_utf8(self.0.clone()) {
297            Ok(str) => write!(f, "\"{}\"", str),             // utf8
298            Err(_) => write!(f, "{}", hex::encode(&self.0)), // non-uf8
299        }
300    }
301}
302
303impl Encodable for WireString {
304    fn consensus_encode<W: Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
305        assert!(!self.0.contains(&0), "WireString cannot contain 0");
306        let mut count = 0;
307        writer.write_all(&self.0)?;
308        count += self.0.len();
309        writer.write_all(&[0])?;
310        count += 1;
311        Ok(count)
312    }
313}
314
315impl Decodable for WireString {
316    fn consensus_decode<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
317        let mut buf = Vec::new();
318        loop {
319            let mut byte = [0; 1];
320            reader.read_exact(&mut byte)?;
321            if byte[0] == 0 {
322                break;
323            }
324            buf.push(byte[0]);
325        }
326        Ok(WireString(buf))
327    }
328}
329
330/// A wrapper around a type that implements `Encodable` and `Decodable` that
331/// prefixes the encoded bytes with the length of the encoded bytes as big-endian
332/// u32.
333#[derive(Clone, Debug)]
334pub struct WithSize<T: Encodable + Decodable + Debug>(pub T);
335
336impl<T: Encodable + Decodable + Debug> Encodable for WithSize<T> {
337    fn consensus_encode<W: Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
338        // compute the size of the encoded bytes by streaming to a sink
339        let mut sink = Sink;
340        let size = self.0.consensus_encode(&mut sink)? as u32;
341        if size > MAX_VEC_SIZE as u32 {
342            return Err(io::Error::new(
343                io::ErrorKind::InvalidInput,
344                "Octets length exceeds MAX_VEC_SIZE",
345            ));
346        }
347        let mut count = 0;
348        count += size.to_be_bytes().consensus_encode(writer)?;
349        count += self.0.consensus_encode(writer)?;
350        Ok(count)
351    }
352}
353
354impl<T: Encodable + Decodable + Debug> Decodable for WithSize<T> {
355    fn consensus_decode<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
356        let len = reader.read_u32_be()?;
357        if len as usize > MAX_VEC_SIZE {
358            return Err(Error::OversizedVectorAllocation {
359                requested: len as usize,
360                max: MAX_VEC_SIZE,
361            });
362        }
363
364        let mut take = Take::new(Box::new(reader), len as u64);
365        let inner = T::consensus_decode(&mut take)?;
366        if !take.is_empty() {
367            return Err(Error::ParseFailed("trailing bytes in WithSize"));
368        }
369        Ok(Self(inner))
370    }
371}
372
373impl<T: Encodable + Decodable + Debug> From<T> for WithSize<T> {
374    fn from(value: T) -> WithSize<T> {
375        WithSize(value)
376    }
377}
378
379impl<T: Encodable + Decodable + Debug> Deref for WithSize<T> {
380    type Target = T;
381
382    fn deref(&self) -> &Self::Target {
383        &self.0
384    }
385}
386
387impl<T: Encodable + Decodable + Debug> DerefMut for WithSize<T> {
388    fn deref_mut(&mut self) -> &mut Self::Target {
389        &mut self.0
390    }
391}
392
393/// Particularly useful for memory constrained environments, this structure avoids
394/// large contiguous memory allocations, and incrementally releases memory as it is consumed.
395/// See GenericChunkedBuffer for details.
396pub struct NonContiguousOctets<const CHUNK_SIZE: usize>(GenericChunkedBuffer<CHUNK_SIZE>);
397
398impl<const CHUNK_SIZE: usize> NonContiguousOctets<CHUNK_SIZE> {
399    /// Creates a new instance of this type, with an empty chunked buffer wrapped inside
400    pub fn new() -> Self {
401        NonContiguousOctets(GenericChunkedBuffer::<CHUNK_SIZE>::new())
402    }
403}
404
405impl<const CHUNK_SIZE: usize> Read for NonContiguousOctets<CHUNK_SIZE> {
406    fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
407        Ok(self.0.read(buf))
408    }
409}
410
411impl<const CHUNK_SIZE: usize> Write for NonContiguousOctets<CHUNK_SIZE> {
412    fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
413        self.0.write(buf);
414        Ok(buf.len())
415    }
416    fn flush(&mut self) -> Result<(), io::Error> {
417        Ok(())
418    }
419}
420
421impl<const CHUNK_SIZE: usize> Encodable for NonContiguousOctets<CHUNK_SIZE> {
422    fn consensus_encode<W: Write + ?Sized>(&self, writer: &mut W) -> Result<usize, io::Error> {
423        let len = self.0.len();
424        let mut count = 0;
425        count += (len as u32).to_be_bytes().consensus_encode(writer)?;
426        for slice in self.0.iter_chunks() {
427            writer.write_all(slice)?;
428        }
429        count += len;
430        Ok(count)
431    }
432}
433
434impl<const CHUNK_SIZE: usize> Decodable for NonContiguousOctets<CHUNK_SIZE> {
435    fn consensus_decode<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
436        let len = reader.read_u32_be()?;
437        if len as usize > MAX_VEC_SIZE {
438            return Err(Error::OversizedVectorAllocation {
439                requested: len as usize,
440                max: MAX_VEC_SIZE,
441            });
442        }
443        let mut reader = reader.take(len as u64);
444        let mut chunk = [0u8; CHUNK_SIZE];
445        let mut buf = GenericChunkedBuffer::<CHUNK_SIZE>::new();
446        let mut nread = 0;
447        while nread < len as usize {
448            let n = reader.read(&mut chunk)?;
449            if n == 0 {
450                return Err(Error::Io(ErrorKind::UnexpectedEof.into()));
451            }
452            buf.write(&chunk[..n]);
453            nread += n;
454        }
455        Ok(NonContiguousOctets(buf))
456    }
457}
458
459impl<const CHUNK_SIZE: usize> Deref for NonContiguousOctets<CHUNK_SIZE> {
460    type Target = GenericChunkedBuffer<CHUNK_SIZE>;
461    fn deref(&self) -> &Self::Target {
462        &self.0
463    }
464}
465
466impl<const CHUNK_SIZE: usize> DerefMut for NonContiguousOctets<CHUNK_SIZE> {
467    fn deref_mut(&mut self) -> &mut GenericChunkedBuffer<CHUNK_SIZE> {
468        &mut self.0
469    }
470}
471
472impl<const CHUNK_SIZE: usize> Default for NonContiguousOctets<CHUNK_SIZE> {
473    fn default() -> Self {
474        NonContiguousOctets::<CHUNK_SIZE>::new()
475    }
476}
477
478impl<const CHUNK_SIZE: usize> From<GenericChunkedBuffer<CHUNK_SIZE>>
479    for NonContiguousOctets<CHUNK_SIZE>
480{
481    fn from(v: GenericChunkedBuffer<CHUNK_SIZE>) -> Self {
482        Self(v)
483    }
484}
485
486/// A reader that reads the bytes of a NonContiguousOctets without mutating it
487pub struct NonContiguousOctetsCursor<'a, const CHUNK_SIZE: usize> {
488    current_slice: Option<&'a [u8]>,
489    chunks_iterator: IterChunk<'a, CHUNK_SIZE>,
490}
491
492impl<'a, const CHUNK_SIZE: usize> NonContiguousOctetsCursor<'a, CHUNK_SIZE> {
493    /// Creates a new instance of this cursor
494    pub fn new(buf: &'a NonContiguousOctets<CHUNK_SIZE>) -> Self {
495        let mut chunks_iterator = buf.iter_chunks();
496        Self {
497            current_slice: chunks_iterator.next(),
498            chunks_iterator,
499        }
500    }
501}
502
503impl<'a, const CHUNK_SIZE: usize> Read for NonContiguousOctetsCursor<'a, CHUNK_SIZE> {
504    fn read(&mut self, buf: &mut [u8]) -> Result<usize, io::Error> {
505        let mut n = usize::MAX;
506        let mut nread = 0;
507        while self.current_slice.is_some() && n > 0 {
508            let slice = self.current_slice.as_mut().unwrap();
509            n = slice.read(&mut buf[nread..])?;
510            nread += n;
511            if slice.is_empty() {
512                self.current_slice = self.chunks_iterator.next();
513            }
514        }
515        Ok(nread)
516    }
517}
518
519/// A trait for reading big-endian integers from a stream
520pub trait ReadBigEndian {
521    /// Read a big-endian u16
522    fn read_u16_be(&mut self) -> Result<u16, Error>;
523    /// Read a big-endian u32
524    fn read_u32_be(&mut self) -> Result<u32, Error>;
525    /// Read a big-endian u64
526    fn read_u64_be(&mut self) -> Result<u64, Error>;
527}
528
529impl<R: Read + ?Sized> ReadBigEndian for R {
530    fn read_u16_be(&mut self) -> Result<u16, Error> {
531        let mut buf = [0; 2];
532        self.read_exact(&mut buf)?;
533        Ok(u16::from_be_bytes(buf))
534    }
535
536    fn read_u32_be(&mut self) -> Result<u32, Error> {
537        let mut buf = [0; 4];
538        self.read_exact(&mut buf)?;
539        Ok(u32::from_be_bytes(buf))
540    }
541
542    fn read_u64_be(&mut self) -> Result<u64, Error> {
543        let mut buf = [0; 8];
544        self.read_exact(&mut buf)?;
545        Ok(u64::from_be_bytes(buf))
546    }
547}
548
549/// A sink that discards all bytes written to it.
550/// core2 is missing this.
551pub struct Sink;
552
553impl Write for Sink {
554    fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
555        Ok(buf.len())
556    }
557
558    fn flush(&mut self) -> Result<(), io::Error> {
559        Ok(())
560    }
561}
562
563/// A trait for types that are encoded with big endian byte order.
564///
565/// This is used for things like `Array<u32>`, so that the elements are encoded as big endian
566pub trait BigEndianEncodable: Encodable + Decodable {
567    /// Encode the object with Big Endian byte order
568    fn consensus_encode_be<W: Write + ?Sized>(&self, writer: &mut W) -> Result<usize, Error>;
569
570    /// Decode the object with Big Endian byte order
571    fn consensus_decode_be<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Error>;
572}
573
574impl BigEndianEncodable for u8 {
575    fn consensus_encode_be<W: Write + ?Sized>(&self, writer: &mut W) -> Result<usize, Error> {
576        writer.write_all(&[*self])?;
577        Ok(1)
578    }
579
580    fn consensus_decode_be<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
581        let mut buf = [0; 1];
582        reader.read_exact(&mut buf)?;
583        Ok(buf[0])
584    }
585}
586
587impl BigEndianEncodable for u16 {
588    fn consensus_encode_be<W: Write + ?Sized>(&self, writer: &mut W) -> Result<usize, Error> {
589        writer.write_all(&self.to_be_bytes())?;
590        Ok(2)
591    }
592
593    fn consensus_decode_be<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
594        let mut buf = [0; 2];
595        reader.read_exact(&mut buf)?;
596        Ok(u16::from_be_bytes(buf))
597    }
598}
599
600impl BigEndianEncodable for u32 {
601    fn consensus_encode_be<W: Write + ?Sized>(&self, writer: &mut W) -> Result<usize, Error> {
602        writer.write_all(&self.to_be_bytes())?;
603        Ok(4)
604    }
605
606    fn consensus_decode_be<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
607        let mut buf = [0; 4];
608        reader.read_exact(&mut buf)?;
609        Ok(u32::from_be_bytes(buf))
610    }
611}
612
613impl BigEndianEncodable for u64 {
614    fn consensus_encode_be<W: Write + ?Sized>(&self, writer: &mut W) -> Result<usize, Error> {
615        writer.write_all(&self.to_be_bytes())?;
616        Ok(8)
617    }
618
619    fn consensus_decode_be<R: Read + ?Sized>(reader: &mut R) -> Result<Self, Error> {
620        let mut buf = [0; 8];
621        reader.read_exact(&mut buf)?;
622        Ok(u64::from_be_bytes(buf))
623    }
624}