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.
5 use std::result::Result;
6 use std::marker::PhantomData;
8 use ln::msgs::DecodeError;
9 use util::ser::{Readable, Writeable, Writer};
11 mod sealed { // You should just use the type aliases instead.
12 pub struct InitContext {}
13 pub struct NodeContext {}
14 pub struct ChannelContext {}
16 /// An internal trait capturing the various feature context types
18 impl Context for InitContext {}
19 impl Context for NodeContext {}
20 impl Context for ChannelContext {}
22 pub trait DataLossProtect: Context {}
23 impl DataLossProtect for InitContext {}
24 impl DataLossProtect for NodeContext {}
26 pub trait InitialRoutingSync: Context {}
27 impl InitialRoutingSync for InitContext {}
29 pub trait UpfrontShutdownScript: Context {}
30 impl UpfrontShutdownScript for InitContext {}
31 impl UpfrontShutdownScript for NodeContext {}
33 pub trait VariableLengthOnion: Context {}
34 impl VariableLengthOnion for InitContext {}
35 impl VariableLengthOnion for NodeContext {}
37 pub trait PaymentSecret: Context {}
38 impl PaymentSecret for InitContext {}
39 impl PaymentSecret for NodeContext {}
41 pub trait BasicMPP: Context {}
42 impl BasicMPP for InitContext {}
43 impl BasicMPP for NodeContext {}
46 /// Tracks the set of features which a node implements, templated by the context in which it
48 pub struct Features<T: sealed::Context> {
49 /// Note that, for convinience, flags is LITTLE endian (despite being big-endian on the wire)
54 impl<T: sealed::Context> Clone for Features<T> {
55 fn clone(&self) -> Self {
57 flags: self.flags.clone(),
62 impl<T: sealed::Context> PartialEq for Features<T> {
63 fn eq(&self, o: &Self) -> bool {
64 self.flags.eq(&o.flags)
67 impl<T: sealed::Context> fmt::Debug for Features<T> {
68 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
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>;
81 /// Create a Features with the features we support
82 pub fn supported() -> InitFeatures {
84 flags: vec![2 | 1 << 5, 1 << (9-8) | 1 << (15 - 8), 1 << (17 - 8*2)],
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());
93 (len as u16).write(w)?;
94 for i in (0..len).rev() {
96 self.flags[i].write(w)?;
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)?;
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()) {
117 impl ChannelFeatures {
118 /// Create a Features with the features we support
119 #[cfg(not(feature = "fuzztarget"))]
120 pub(crate) fn supported() -> ChannelFeatures {
126 #[cfg(feature = "fuzztarget")]
127 pub fn supported() -> ChannelFeatures {
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, }
143 /// Create a Features with the features we support
144 #[cfg(not(feature = "fuzztarget"))]
145 pub(crate) fn supported() -> NodeFeatures {
147 flags: vec![2 | 1 << 5, 1 << (9-8) | 1 << (15 - 8), 1 << (17 - 8*2)],
151 #[cfg(feature = "fuzztarget")]
152 pub fn supported() -> NodeFeatures {
154 flags: vec![2 | 1 << 5, 1 << (9-8) | 1 << (15 - 8), 1 << (17 - 8*2)],
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);
167 Self { flags, mark: PhantomData, }
171 impl<T: sealed::Context> Features<T> {
172 /// Create a blank Features with no features set
173 pub fn empty() -> Features<T> {
181 /// Create a Features given a set of flags, in LE.
182 pub fn from_le_bytes(flags: Vec<u8>) -> Features<T> {
190 /// Gets the underlying flags set, in LE.
191 pub fn le_flags(&self) -> &Vec<u8> {
195 pub(crate) fn requires_unknown_bits(&self) -> bool {
196 self.flags.iter().enumerate().any(|(idx, &byte)| {
198 0 => (byte & 0b01000100),
199 1 => (byte & 0b00010100),
200 2 => (byte & 0b01010100),
201 _ => (byte & 0b01010101),
206 pub(crate) fn supports_unknown_bits(&self) -> bool {
207 self.flags.iter().enumerate().any(|(idx, &byte)| {
209 0 => (byte & 0b11000100),
210 1 => (byte & 0b00111100),
211 2 => (byte & 0b11111100),
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 {
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;
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);
238 if self.flags.len() == 2 && self.flags[1] == 0 {
239 self.flags.resize(1, 0u8);
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
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
255 pub(crate) fn unset_upfront_shutdown_script(&mut self) {
256 self.flags[0] ^= 1 << 5;
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
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
270 pub(crate) fn set_initial_routing_sync(&mut self) {
271 if self.flags.len() == 0 {
272 self.flags.resize(1, 1 << 3);
274 self.flags[0] |= 1 << 3;
279 impl<T: sealed::PaymentSecret> Features<T> {
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
288 impl<T: sealed::BasicMPP> Features<T> {
289 // We currently never test for this since we don't actually *generate* multipath routes.
291 pub(crate) fn basic_mpp(&self) -> bool {
292 self.flags.len() > 2 && (self.flags[2] & (3 << (16-8*2))) != 0
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
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
320 use super::{ChannelFeatures, InitFeatures, NodeFeatures};
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());
331 assert!(InitFeatures::supported().supports_upfront_shutdown_script());
332 assert!(NodeFeatures::supported().supports_upfront_shutdown_script());
334 assert!(InitFeatures::supported().supports_data_loss_protect());
335 assert!(NodeFeatures::supported().supports_data_loss_protect());
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());
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());