lightning/ln/
features.rs

1// This file is Copyright its original authors, visible in version control
2// history.
3//
4// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7// You may not use this file except in accordance with one or both of these
8// licenses.
9
10//! Implementations of extensions on features.
11
12use lightning_types::features::ChannelTypeFeatures;
13use lightning_types::features::{BlindedHopFeatures, Bolt12InvoiceFeatures};
14use lightning_types::features::{Bolt11InvoiceFeatures, InvoiceRequestFeatures, OfferFeatures};
15use lightning_types::features::{ChannelFeatures, InitFeatures, NodeFeatures};
16
17#[allow(unused_imports)]
18use crate::prelude::*;
19
20use crate::ln::msgs::DecodeError;
21use crate::util::ser::{Readable, WithoutLength, Writeable, Writer};
22use crate::{io, io_extras};
23
24fn write_be<W: Writer>(w: &mut W, le_flags: &[u8]) -> Result<(), io::Error> {
25	// Swap back to big-endian
26	for f in le_flags.iter().rev() {
27		f.write(w)?;
28	}
29	Ok(())
30}
31
32macro_rules! impl_feature_len_prefixed_write {
33	($features: ident) => {
34		impl Writeable for $features {
35			fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
36				let bytes = self.le_flags();
37				(bytes.len() as u16).write(w)?;
38				write_be(w, bytes)
39			}
40		}
41		impl Readable for $features {
42			fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
43				Ok(Self::from_be_bytes(Vec::<u8>::read(r)?))
44			}
45		}
46	};
47}
48impl_feature_len_prefixed_write!(InitFeatures);
49impl_feature_len_prefixed_write!(ChannelFeatures);
50impl_feature_len_prefixed_write!(NodeFeatures);
51impl_feature_len_prefixed_write!(Bolt11InvoiceFeatures);
52impl_feature_len_prefixed_write!(Bolt12InvoiceFeatures);
53impl_feature_len_prefixed_write!(BlindedHopFeatures);
54
55// Some features only appear inside of TLVs, so they don't have a length prefix when serialized.
56macro_rules! impl_feature_tlv_write {
57	($features: ident) => {
58		impl Writeable for $features {
59			fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
60				WithoutLength(self).write(w)
61			}
62		}
63		impl Readable for $features {
64			fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
65				Ok(WithoutLength::<Self>::read(r)?.0)
66			}
67		}
68	};
69}
70
71impl_feature_tlv_write!(ChannelTypeFeatures);
72
73// Some features may appear both in a TLV record and as part of a TLV subtype sequence. The latter
74// requires a length but the former does not.
75
76macro_rules! impl_feature_write_without_length {
77	($features: ident) => {
78		impl Writeable for WithoutLength<&$features> {
79			fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
80				write_be(w, self.0.le_flags())
81			}
82		}
83
84		impl Readable for WithoutLength<$features> {
85			fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
86				let v = io_extras::read_to_end(r)?;
87				Ok(WithoutLength($features::from_be_bytes(v)))
88			}
89		}
90	};
91}
92
93impl_feature_write_without_length!(Bolt12InvoiceFeatures);
94impl_feature_write_without_length!(ChannelTypeFeatures);
95impl_feature_write_without_length!(InvoiceRequestFeatures);
96impl_feature_write_without_length!(OfferFeatures);
97impl_feature_write_without_length!(BlindedHopFeatures);
98
99#[cfg(test)]
100mod tests {
101	use super::*;
102	use crate::util::ser::{Readable, WithoutLength, Writeable};
103
104	#[test]
105	fn encodes_features_without_length() {
106		let features = OfferFeatures::from_le_bytes(vec![1, 2, 3, 4, 5, 42, 100, 101]);
107		assert_eq!(features.le_flags().len(), 8);
108
109		let mut serialized_features = Vec::new();
110		WithoutLength(&features).write(&mut serialized_features).unwrap();
111		assert_eq!(serialized_features.len(), 8);
112
113		let deserialized_features =
114			WithoutLength::<OfferFeatures>::read(&mut &serialized_features[..]).unwrap().0;
115		assert_eq!(features, deserialized_features);
116	}
117}