Expand the Route object to include multiple paths.
[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         pub trait PaymentSecret: Context {}
38         impl PaymentSecret for InitContext {}
39         impl PaymentSecret for NodeContext {}
40
41         pub trait BasicMPP: Context {}
42         impl BasicMPP for InitContext {}
43         impl BasicMPP for NodeContext {}
44 }
45
46 /// Tracks the set of features which a node implements, templated by the context in which it
47 /// appears.
48 pub struct Features<T: sealed::Context> {
49         /// Note that, for convinience, flags is LITTLE endian (despite being big-endian on the wire)
50         flags: Vec<u8>,
51         mark: PhantomData<T>,
52 }
53
54 impl<T: sealed::Context> Clone for Features<T> {
55         fn clone(&self) -> Self {
56                 Self {
57                         flags: self.flags.clone(),
58                         mark: PhantomData,
59                 }
60         }
61 }
62 impl<T: sealed::Context> PartialEq for Features<T> {
63         fn eq(&self, o: &Self) -> bool {
64                 self.flags.eq(&o.flags)
65         }
66 }
67 impl<T: sealed::Context> fmt::Debug for Features<T> {
68         fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
69                 self.flags.fmt(fmt)
70         }
71 }
72
73 /// A feature message as it appears in an init message
74 pub type InitFeatures = Features<sealed::InitContext>;
75 /// A feature message as it appears in a node_announcement message
76 pub type NodeFeatures = Features<sealed::NodeContext>;
77 /// A feature message as it appears in a channel_announcement message
78 pub type ChannelFeatures = Features<sealed::ChannelContext>;
79
80 impl InitFeatures {
81         /// Create a Features with the features we support
82         pub fn supported() -> InitFeatures {
83                 InitFeatures {
84                         flags: vec![2 | 1 << 5, 1 << (9-8) | 1 << (15 - 8), 1 << (17 - 8*2)],
85                         mark: PhantomData,
86                 }
87         }
88
89         /// Writes all features present up to, and including, 13.
90         pub(crate) fn write_up_to_13<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
91                 let len = cmp::min(2, self.flags.len());
92                 w.size_hint(len + 2);
93                 (len as u16).write(w)?;
94                 for i in (0..len).rev() {
95                         if i == 0 {
96                                 self.flags[i].write(w)?;
97                         } else {
98                                 // On byte 1, we want up-to-and-including-bit-13, 0-indexed, which is
99                                 // up-to-and-including-bit-5, 0-indexed, on this byte:
100                                 (self.flags[i] & 0b00_11_11_11).write(w)?;
101                         }
102                 }
103                 Ok(())
104         }
105
106         /// or's another InitFeatures into this one.
107         pub(crate) fn or(mut self, o: InitFeatures) -> InitFeatures {
108                 let total_feature_len = cmp::max(self.flags.len(), o.flags.len());
109                 self.flags.resize(total_feature_len, 0u8);
110                 for (byte, o_byte) in self.flags.iter_mut().zip(o.flags.iter()) {
111                         *byte |= *o_byte;
112                 }
113                 self
114         }
115 }
116
117 impl ChannelFeatures {
118         /// Create a Features with the features we support
119         #[cfg(not(feature = "fuzztarget"))]
120         pub(crate) fn supported() -> ChannelFeatures {
121                 ChannelFeatures {
122                         flags: Vec::new(),
123                         mark: PhantomData,
124                 }
125         }
126         #[cfg(feature = "fuzztarget")]
127         pub fn supported() -> ChannelFeatures {
128                 ChannelFeatures {
129                         flags: Vec::new(),
130                         mark: PhantomData,
131                 }
132         }
133
134         /// Takes the flags that we know how to interpret in an init-context features that are also
135         /// relevant in a channel-context features and creates a channel-context features from them.
136         pub(crate) fn with_known_relevant_init_flags(_init_ctx: &InitFeatures) -> Self {
137                 // There are currently no channel flags defined that we understand.
138                 Self { flags: Vec::new(), mark: PhantomData, }
139         }
140 }
141
142 impl NodeFeatures {
143         /// Create a Features with the features we support
144         #[cfg(not(feature = "fuzztarget"))]
145         pub(crate) fn supported() -> NodeFeatures {
146                 NodeFeatures {
147                         flags: vec![2 | 1 << 5, 1 << (9-8) | 1 << (15 - 8), 1 << (17 - 8*2)],
148                         mark: PhantomData,
149                 }
150         }
151         #[cfg(feature = "fuzztarget")]
152         pub fn supported() -> NodeFeatures {
153                 NodeFeatures {
154                         flags: vec![2 | 1 << 5, 1 << (9-8) | 1 << (15 - 8), 1 << (17 - 8*2)],
155                         mark: PhantomData,
156                 }
157         }
158
159         /// Takes the flags that we know how to interpret in an init-context features that are also
160         /// relevant in a node-context features and creates a node-context features from them.
161         pub(crate) fn with_known_relevant_init_flags(init_ctx: &InitFeatures) -> Self {
162                 let mut flags = Vec::new();
163                 if init_ctx.flags.len() > 0 {
164                         // Pull out data_loss_protect and upfront_shutdown_script (bits 0, 1, 4, and 5)
165                         flags.push(init_ctx.flags.last().unwrap() & 0b00110011);
166                 }
167                 Self { flags, mark: PhantomData, }
168         }
169 }
170
171 impl<T: sealed::Context> Features<T> {
172         /// Create a blank Features with no features set
173         pub fn empty() -> Features<T> {
174                 Features {
175                         flags: Vec::new(),
176                         mark: PhantomData,
177                 }
178         }
179
180         #[cfg(test)]
181         /// Create a Features given a set of flags, in LE.
182         pub fn from_le_bytes(flags: Vec<u8>) -> Features<T> {
183                 Features {
184                         flags,
185                         mark: PhantomData,
186                 }
187         }
188
189         #[cfg(test)]
190         /// Gets the underlying flags set, in LE.
191         pub fn le_flags(&self) -> &Vec<u8> {
192                 &self.flags
193         }
194
195         pub(crate) fn requires_unknown_bits(&self) -> bool {
196                 self.flags.iter().enumerate().any(|(idx, &byte)| {
197                         (match idx {
198                                 0 => (byte & 0b01000100),
199                                 1 => (byte & 0b00010100),
200                                 2 => (byte & 0b01010100),
201                                 _ => (byte & 0b01010101),
202                         }) != 0
203                 })
204         }
205
206         pub(crate) fn supports_unknown_bits(&self) -> bool {
207                 self.flags.iter().enumerate().any(|(idx, &byte)| {
208                         (match idx {
209                                 0 => (byte & 0b11000100),
210                                 1 => (byte & 0b00111100),
211                                 2 => (byte & 0b11111100),
212                                 _ => byte,
213                         }) != 0
214                 })
215         }
216
217         /// The number of bytes required to represent the feature flags present. This does not include
218         /// the length bytes which are included in the serialized form.
219         pub(crate) fn byte_count(&self) -> usize {
220                 self.flags.len()
221         }
222
223         #[cfg(test)]
224         pub(crate) fn set_require_unknown_bits(&mut self) {
225                 let newlen = cmp::max(3, self.flags.len());
226                 self.flags.resize(newlen, 0u8);
227                 self.flags[2] |= 0x40;
228         }
229
230         #[cfg(test)]
231         pub(crate) fn clear_require_unknown_bits(&mut self) {
232                 let newlen = cmp::max(3, self.flags.len());
233                 self.flags.resize(newlen, 0u8);
234                 self.flags[2] &= !0x40;
235                 if self.flags.len() == 3 && self.flags[2] == 0 {
236                         self.flags.resize(2, 0u8);
237                 }
238                 if self.flags.len() == 2 && self.flags[1] == 0 {
239                         self.flags.resize(1, 0u8);
240                 }
241         }
242 }
243
244 impl<T: sealed::DataLossProtect> Features<T> {
245         pub(crate) fn supports_data_loss_protect(&self) -> bool {
246                 self.flags.len() > 0 && (self.flags[0] & 3) != 0
247         }
248 }
249
250 impl<T: sealed::UpfrontShutdownScript> Features<T> {
251         pub(crate) fn supports_upfront_shutdown_script(&self) -> bool {
252                 self.flags.len() > 0 && (self.flags[0] & (3 << 4)) != 0
253         }
254         #[cfg(test)]
255         pub(crate) fn unset_upfront_shutdown_script(&mut self) {
256                 self.flags[0] ^= 1 << 5;
257         }
258 }
259
260 impl<T: sealed::VariableLengthOnion> Features<T> {
261         pub(crate) fn supports_variable_length_onion(&self) -> bool {
262                 self.flags.len() > 1 && (self.flags[1] & 3) != 0
263         }
264 }
265
266 impl<T: sealed::InitialRoutingSync> Features<T> {
267         pub(crate) fn initial_routing_sync(&self) -> bool {
268                 self.flags.len() > 0 && (self.flags[0] & (1 << 3)) != 0
269         }
270         pub(crate) fn set_initial_routing_sync(&mut self) {
271                 if self.flags.len() == 0 {
272                         self.flags.resize(1, 1 << 3);
273                 } else {
274                         self.flags[0] |= 1 << 3;
275                 }
276         }
277 }
278
279 impl<T: sealed::PaymentSecret> Features<T> {
280         #[allow(dead_code)]
281         // Note that we never need to test this since what really matters is the invoice - iff the
282         // invoice provides a payment_secret, we assume all the way through that we can do MPP.
283         pub(crate) fn payment_secret(&self) -> bool {
284                 self.flags.len() > 1 && (self.flags[1] & (3 << (12-8))) != 0
285         }
286 }
287
288 impl<T: sealed::BasicMPP> Features<T> {
289         // We currently never test for this since we don't actually *generate* multipath routes.
290         #[allow(dead_code)]
291         pub(crate) fn basic_mpp(&self) -> bool {
292                 self.flags.len() > 2 && (self.flags[2] & (3 << (16-8*2))) != 0
293         }
294 }
295
296 impl<T: sealed::Context> Writeable for Features<T> {
297         fn write<W: Writer>(&self, w: &mut W) -> Result<(), ::std::io::Error> {
298                 w.size_hint(self.flags.len() + 2);
299                 (self.flags.len() as u16).write(w)?;
300                 for f in self.flags.iter().rev() { // Swap back to big-endian
301                         f.write(w)?;
302                 }
303                 Ok(())
304         }
305 }
306
307 impl<R: ::std::io::Read, T: sealed::Context> Readable<R> for Features<T> {
308         fn read(r: &mut R) -> Result<Self, DecodeError> {
309                 let mut flags: Vec<u8> = Readable::read(r)?;
310                 flags.reverse(); // Swap to little-endian
311                 Ok(Self {
312                         flags,
313                         mark: PhantomData,
314                 })
315         }
316 }
317
318 #[cfg(test)]
319 mod tests {
320         use super::{ChannelFeatures, InitFeatures, NodeFeatures};
321
322         #[test]
323         fn sanity_test_our_features() {
324                 assert!(!ChannelFeatures::supported().requires_unknown_bits());
325                 assert!(!ChannelFeatures::supported().supports_unknown_bits());
326                 assert!(!InitFeatures::supported().requires_unknown_bits());
327                 assert!(!InitFeatures::supported().supports_unknown_bits());
328                 assert!(!NodeFeatures::supported().requires_unknown_bits());
329                 assert!(!NodeFeatures::supported().supports_unknown_bits());
330
331                 assert!(InitFeatures::supported().supports_upfront_shutdown_script());
332                 assert!(NodeFeatures::supported().supports_upfront_shutdown_script());
333
334                 assert!(InitFeatures::supported().supports_data_loss_protect());
335                 assert!(NodeFeatures::supported().supports_data_loss_protect());
336
337                 let mut init_features = InitFeatures::supported();
338                 init_features.set_initial_routing_sync();
339                 assert!(!init_features.requires_unknown_bits());
340                 assert!(!init_features.supports_unknown_bits());
341         }
342
343         #[test]
344         fn sanity_test_unkown_bits_testing() {
345                 let mut features = ChannelFeatures::supported();
346                 features.set_require_unknown_bits();
347                 assert!(features.requires_unknown_bits());
348                 features.clear_require_unknown_bits();
349                 assert!(!features.requires_unknown_bits());
350         }
351 }