1use 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 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
55macro_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
73macro_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}