Merge pull request #472 from TheBlueMatt/2020-01-net-async-await
[rust-lightning] / lightning / src / ln / features.rs
1 //! Lightning exposes sets of supported operations through "feature flags". This module includes
2 //! types to store those feature flags and query for specific flags.
3
4 use std::{cmp, fmt};
5 use std::result::Result;
6 use std::marker::PhantomData;
7
8 use ln::msgs::DecodeError;
9 use util::ser::{Readable, Writeable, Writer};
10
11 mod sealed { // You should just use the type aliases instead.
12         pub struct InitContext {}
13         pub struct NodeContext {}
14         pub struct ChannelContext {}
15
16         /// An internal trait capturing the various feature context types
17         pub trait Context {}
18         impl Context for InitContext {}
19         impl Context for NodeContext {}
20         impl Context for ChannelContext {}
21
22         pub trait DataLossProtect: Context {}
23         impl DataLossProtect for InitContext {}
24         impl DataLossProtect for NodeContext {}
25
26         pub trait InitialRoutingSync: Context {}
27         impl InitialRoutingSync for InitContext {}
28
29         pub trait UpfrontShutdownScript: Context {}
30         impl UpfrontShutdownScript for InitContext {}
31         impl UpfrontShutdownScript for NodeContext {}
32
33         pub trait VariableLengthOnion: Context {}
34         impl VariableLengthOnion for InitContext {}
35         impl VariableLengthOnion for NodeContext {}
36 }
37
38 /// Tracks the set of features which a node implements, templated by the context in which it
39 /// appears.
40 pub struct Features<T: sealed::Context> {
41         /// Note that, for convinience, flags is LITTLE endian (despite being big-endian on the wire)
42         flags: Vec<u8>,
43         mark: PhantomData<T>,
44 }
45
46 impl<T: sealed::Context> Clone for Features<T> {
47         fn clone(&self) -> Self {
48                 Self {
49                         flags: self.flags.clone(),
50                         mark: PhantomData,
51                 }
52         }
53 }
54 impl<T: sealed::Context> PartialEq for Features<T> {
55         fn eq(&self, o: &Self) -> bool {
56                 self.flags.eq(&o.flags)
57         }
58 }
59 impl<T: sealed::Context> fmt::Debug for Features<T> {
60         fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
61                 self.flags.fmt(fmt)
62         }
63 }
64
65 /// A feature message as it appears in an init message
66 pub type InitFeatures = Features<sealed::InitContext>;
67 /// A feature message as it appears in a node_announcement message
68 pub type NodeFeatures = Features<sealed::NodeContext>;
69 /// A feature message as it appears in a channel_announcement message
70 pub type ChannelFeatures = Features<sealed::ChannelContext>;
71
72 impl InitFeatures {
73         /// Create a Features with the features we support
74         pub fn supported() -> InitFeatures {
75                 InitFeatures {
76                         flags: vec![2 | 1 << 5, 1 << (9-8)],
77                         mark: PhantomData,
78                 }
79         }
80
81         /// Writes all features present up to, and including, 13.
82         pub(crate) fn write_up_to_13<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
83                 let len = cmp::min(2, self.flags.len());
84                 w.size_hint(len + 2);
85                 (len as u16).write(w)?;
86                 for i in (0..len).rev() {
87                         if i == 0 {
88                                 self.flags[i].write(w)?;
89                         } else {
90                                 // On byte 1, we want up-to-and-including-bit-13, 0-indexed, which is
91                                 // up-to-and-including-bit-5, 0-indexed, on this byte:
92                                 (self.flags[i] & 0b00_11_11_11).write(w)?;
93                         }
94                 }
95                 Ok(())
96         }
97
98         /// or's another InitFeatures into this one.
99         pub(crate) fn or(mut self, o: InitFeatures) -> InitFeatures {
100                 let total_feature_len = cmp::max(self.flags.len(), o.flags.len());
101                 self.flags.resize(total_feature_len, 0u8);
102                 for (byte, o_byte) in self.flags.iter_mut().zip(o.flags.iter()) {
103                         *byte |= *o_byte;
104                 }
105                 self
106         }
107 }
108
109 impl ChannelFeatures {
110         /// Create a Features with the features we support
111         #[cfg(not(feature = "fuzztarget"))]
112         pub(crate) fn supported() -> ChannelFeatures {
113                 ChannelFeatures {
114                         flags: Vec::new(),
115                         mark: PhantomData,
116                 }
117         }
118         #[cfg(feature = "fuzztarget")]
119         pub fn supported() -> ChannelFeatures {
120                 ChannelFeatures {
121                         flags: Vec::new(),
122                         mark: PhantomData,
123                 }
124         }
125
126         /// Takes the flags that we know how to interpret in an init-context features that are also
127         /// relevant in a channel-context features and creates a channel-context features from them.
128         pub(crate) fn with_known_relevant_init_flags(_init_ctx: &InitFeatures) -> Self {
129                 // There are currently no channel flags defined that we understand.
130                 Self { flags: Vec::new(), mark: PhantomData, }
131         }
132 }
133
134 impl NodeFeatures {
135         /// Create a Features with the features we support
136         #[cfg(not(feature = "fuzztarget"))]
137         pub(crate) fn supported() -> NodeFeatures {
138                 NodeFeatures {
139                         flags: vec![2 | 1 << 5, 1 << (9-8)],
140                         mark: PhantomData,
141                 }
142         }
143         #[cfg(feature = "fuzztarget")]
144         pub fn supported() -> NodeFeatures {
145                 NodeFeatures {
146                         flags: vec![2 | 1 << 5, 1 << (9-8)],
147                         mark: PhantomData,
148                 }
149         }
150
151         /// Takes the flags that we know how to interpret in an init-context features that are also
152         /// relevant in a node-context features and creates a node-context features from them.
153         /// Be sure to blank out features that are unknown to us.
154         pub(crate) fn with_known_relevant_init_flags(init_ctx: &InitFeatures) -> Self {
155                 let mut flags = Vec::new();
156                 for (i, feature_byte)in init_ctx.flags.iter().enumerate() {
157                         match i {
158                                 // Blank out initial_routing_sync (feature bits 2/3), gossip_queries (6/7),
159                                 // gossip_queries_ex (10/11), option_static_remotekey (12/13), and
160                                 // payment_secret (14/15)
161                                 0 => flags.push(feature_byte & 0b00110011),
162                                 1 => flags.push(feature_byte & 0b00000011),
163                                 _ => (),
164                         }
165                 }
166                 Self { flags, mark: PhantomData, }
167         }
168 }
169
170 impl<T: sealed::Context> Features<T> {
171         /// Create a blank Features with no features set
172         pub fn empty() -> Features<T> {
173                 Features {
174                         flags: Vec::new(),
175                         mark: PhantomData,
176                 }
177         }
178
179         #[cfg(test)]
180         /// Create a Features given a set of flags, in LE.
181         pub fn from_le_bytes(flags: Vec<u8>) -> Features<T> {
182                 Features {
183                         flags,
184                         mark: PhantomData,
185                 }
186         }
187
188         #[cfg(test)]
189         /// Gets the underlying flags set, in LE.
190         pub fn le_flags(&self) -> &Vec<u8> {
191                 &self.flags
192         }
193
194         pub(crate) fn requires_unknown_bits(&self) -> bool {
195                 self.flags.iter().enumerate().any(|(idx, &byte)| {
196                         (match idx {
197                                 // Unknown bits are even bits which we don't understand, we list ones which we do
198                                 // here:
199                                 // unknown, upfront_shutdown_script, unknown (actually initial_routing_sync, but it
200                                 // is only valid as an optional feature), and data_loss_protect:
201                                 0 => (byte & 0b01000100),
202                                 // unknown, unknown, unknown, var_onion_optin:
203                                 1 => (byte & 0b01010100),
204                                 // fallback, all even bits set:
205                                 _ => (byte & 0b01010101),
206                         }) != 0
207                 })
208         }
209
210         pub(crate) fn supports_unknown_bits(&self) -> bool {
211                 self.flags.iter().enumerate().any(|(idx, &byte)| {
212                         (match idx {
213                                 // unknown, upfront_shutdown_script, initial_routing_sync (is only valid as an
214                                 // optional feature), and data_loss_protect:
215                                 0 => (byte & 0b11000100),
216                                 // unknown, unknown, unknown, var_onion_optin:
217                                 1 => (byte & 0b11111100),
218                                 _ => byte,
219                         }) != 0
220                 })
221         }
222
223         /// The number of bytes required to represent the feature flags present. This does not include
224         /// the length bytes which are included in the serialized form.
225         pub(crate) fn byte_count(&self) -> usize {
226                 self.flags.len()
227         }
228
229         #[cfg(test)]
230         pub(crate) fn set_require_unknown_bits(&mut self) {
231                 let newlen = cmp::max(2, self.flags.len());
232                 self.flags.resize(newlen, 0u8);
233                 self.flags[1] |= 0x40;
234         }
235
236         #[cfg(test)]
237         pub(crate) fn clear_require_unknown_bits(&mut self) {
238                 let newlen = cmp::max(2, self.flags.len());
239                 self.flags.resize(newlen, 0u8);
240                 self.flags[1] &= !0x40;
241                 if self.flags.len() == 2 && self.flags[1] == 0 {
242                         self.flags.resize(1, 0u8);
243                 }
244         }
245 }
246
247 impl<T: sealed::DataLossProtect> Features<T> {
248         pub(crate) fn supports_data_loss_protect(&self) -> bool {
249                 self.flags.len() > 0 && (self.flags[0] & 3) != 0
250         }
251 }
252
253 impl<T: sealed::UpfrontShutdownScript> Features<T> {
254         pub(crate) fn supports_upfront_shutdown_script(&self) -> bool {
255                 self.flags.len() > 0 && (self.flags[0] & (3 << 4)) != 0
256         }
257         #[cfg(test)]
258         pub(crate) fn unset_upfront_shutdown_script(&mut self) {
259                 self.flags[0] ^= 1 << 5;
260         }
261 }
262
263 impl<T: sealed::VariableLengthOnion> Features<T> {
264         pub(crate) fn supports_variable_length_onion(&self) -> bool {
265                 self.flags.len() > 1 && (self.flags[1] & 3) != 0
266         }
267 }
268
269 impl<T: sealed::InitialRoutingSync> Features<T> {
270         pub(crate) fn initial_routing_sync(&self) -> bool {
271                 self.flags.len() > 0 && (self.flags[0] & (1 << 3)) != 0
272         }
273         pub(crate) fn set_initial_routing_sync(&mut self) {
274                 if self.flags.len() == 0 {
275                         self.flags.resize(1, 1 << 3);
276                 } else {
277                         self.flags[0] |= 1 << 3;
278                 }
279         }
280 }
281
282 impl<T: sealed::Context> Writeable for Features<T> {
283         fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
284                 w.size_hint(self.flags.len() + 2);
285                 (self.flags.len() as u16).write(w)?;
286                 for f in self.flags.iter().rev() { // Swap back to big-endian
287                         f.write(w)?;
288                 }
289                 Ok(())
290         }
291 }
292
293 impl<T: sealed::Context> Readable for Features<T> {
294         fn read<R: ::std::io::Read>(r: &mut R) -> Result<Self, DecodeError> {
295                 let mut flags: Vec<u8> = Readable::read(r)?;
296                 flags.reverse(); // Swap to little-endian
297                 Ok(Self {
298                         flags,
299                         mark: PhantomData,
300                 })
301         }
302 }
303
304 #[cfg(test)]
305 mod tests {
306         use super::{ChannelFeatures, InitFeatures, NodeFeatures, Features};
307
308         #[test]
309         fn sanity_test_our_features() {
310                 assert!(!ChannelFeatures::supported().requires_unknown_bits());
311                 assert!(!ChannelFeatures::supported().supports_unknown_bits());
312                 assert!(!InitFeatures::supported().requires_unknown_bits());
313                 assert!(!InitFeatures::supported().supports_unknown_bits());
314                 assert!(!NodeFeatures::supported().requires_unknown_bits());
315                 assert!(!NodeFeatures::supported().supports_unknown_bits());
316
317                 assert!(InitFeatures::supported().supports_upfront_shutdown_script());
318                 assert!(NodeFeatures::supported().supports_upfront_shutdown_script());
319
320                 assert!(InitFeatures::supported().supports_data_loss_protect());
321                 assert!(NodeFeatures::supported().supports_data_loss_protect());
322
323                 assert!(InitFeatures::supported().supports_variable_length_onion());
324                 assert!(NodeFeatures::supported().supports_variable_length_onion());
325
326                 let mut init_features = InitFeatures::supported();
327                 init_features.set_initial_routing_sync();
328                 assert!(!init_features.requires_unknown_bits());
329                 assert!(!init_features.supports_unknown_bits());
330         }
331
332         #[test]
333         fn sanity_test_unkown_bits_testing() {
334                 let mut features = ChannelFeatures::supported();
335                 features.set_require_unknown_bits();
336                 assert!(features.requires_unknown_bits());
337                 features.clear_require_unknown_bits();
338                 assert!(!features.requires_unknown_bits());
339         }
340
341         #[test]
342         fn test_node_with_known_relevant_init_flags() {
343                 // Create an InitFeatures with initial_routing_sync supported.
344                 let mut init_features = InitFeatures::supported();
345                 init_features.set_initial_routing_sync();
346
347                 // Attempt to pull out non-node-context feature flags from these InitFeatures.
348                 let res = NodeFeatures::with_known_relevant_init_flags(&init_features);
349
350                 {
351                         // Check that the flags are as expected: optional_data_loss_protect,
352                         // option_upfront_shutdown_script, and var_onion_optin set.
353                         assert_eq!(res.flags[0], 0b00100010);
354                         assert_eq!(res.flags[1], 0b00000010);
355                         assert_eq!(res.flags.len(), 2);
356                 }
357
358                 // Check that the initial_routing_sync feature was correctly blanked out.
359                 let new_features: InitFeatures = Features::from_le_bytes(res.flags);
360                 assert!(!new_features.initial_routing_sync());
361         }
362 }