lightning_encoding/
lib.rs

1// Network encoding for lightning network peer protocol data types
2// Written in 2020-2022 by
3//     Dr. Maxim Orlovsky <orlovsky@pandoracore.com>
4//
5// To the extent possible under law, the author(s) have dedicated all
6// copyright and related and neighboring rights to this software to
7// the public domain worldwide. This software is distributed without
8// any warranty.
9//
10// You should have received a copy of the MIT License
11// along with this software.
12// If not, see <https://opensource.org/licenses/MIT>.
13
14#![recursion_limit = "256"]
15// Coding conventions
16#![deny(
17    non_upper_case_globals,
18    non_camel_case_types,
19    non_snake_case,
20    unused_mut,
21    unused_imports,
22    dead_code,
23    //missing_docs
24)]
25
26#[cfg(feature = "derive")]
27#[allow(unused_imports)]
28#[macro_use]
29extern crate lightning_encoding_derive as derive;
30#[cfg(feature = "derive")]
31pub use derive::{LightningDecode, LightningEncode};
32
33#[allow(unused_imports)]
34#[macro_use]
35extern crate amplify;
36
37mod big_size;
38mod bitcoin;
39mod byte_str;
40mod collections;
41mod error;
42// mod net; - no need in encoding network addresses for lightning p2p protocol
43mod primitives;
44pub mod strategies;
45
46// -----------------------------------------------------------------------------
47use std::io;
48
49pub use big_size::BigSize;
50pub use error::Error;
51pub use strategies::Strategy;
52pub use strict_encoding::TlvError;
53
54/// Lightning-network specific encoding as defined in BOLT-1, 2, 3...
55pub trait LightningEncode {
56    /// Encode with the given [`std::io::Write`] instance; must return result
57    /// with either amount of bytes encoded – or implementation-specific
58    /// error type.
59    fn lightning_encode<E: io::Write>(&self, e: E) -> Result<usize, Error>;
60
61    /// Serializes data as a byte array using
62    /// [`LightningEncode::lightning_encode`] function.
63    fn lightning_serialize(&self) -> Result<Vec<u8>, Error> {
64        let mut encoder = vec![];
65        self.lightning_encode(&mut encoder)?;
66        Ok(encoder)
67    }
68}
69
70/// Lightning-network specific encoding as defined in BOLT-1, 2, 3...
71pub trait LightningDecode
72where
73    Self: Sized,
74{
75    /// Decode with the given [`std::io::Read`] instance; must either
76    /// construct an instance or return implementation-specific error type.
77    fn lightning_decode<D: io::Read>(d: D) -> Result<Self, Error>;
78
79    /// Tries to deserialize byte array into the current type using
80    /// [`LightningDecode::lightning_decode`] function.
81    fn lightning_deserialize(data: impl AsRef<[u8]>) -> Result<Self, Error> {
82        let mut decoder = io::Cursor::new(data.as_ref());
83        let rv = Self::lightning_decode(&mut decoder)?;
84        let consumed = decoder.position() as usize;
85
86        // Fail if data are not consumed entirely.
87        if consumed == data.as_ref().len() {
88            Ok(rv)
89        } else {
90            Err(Error::DataNotEntirelyConsumed)
91        }
92    }
93}
94
95/// Convenience method for strict encoding of data structures implementing
96/// [`LightningEncode`] into a byte vector.
97pub fn lightning_serialize<T>(data: &T) -> Result<Vec<u8>, Error>
98where
99    T: LightningEncode,
100{
101    data.lightning_serialize()
102}
103
104/// Convenience method for strict decoding of data structures implementing
105/// [`LightningDecode`] from any byt data source.
106pub fn lightning_deserialize<T>(data: impl AsRef<[u8]>) -> Result<T, Error>
107where
108    T: LightningDecode,
109{
110    T::lightning_deserialize(data)
111}