1 //! Feature flag definitions for the Lightning protocol according to [BOLT #9].
3 //! Lightning nodes advertise a supported set of operation through feature flags. Features are
4 //! applicable for a specific context as indicated in some [messages]. [`Features`] encapsulates
5 //! behavior for specifying and checking feature flags for a particular context. Each feature is
6 //! defined internally by a trait specifying the corresponding flags (i.e., even and odd bits). A
7 //! [`Context`] is used to parameterize [`Features`] and defines which features it can support.
9 //! Whether a feature is considered \"known\" or \"unknown\" is relative to the implementation, whereas
10 //! the term \"supports\" is used in reference to a particular set of [`Features`]. That is, a node
11 //! supports a feature if it advertises the feature (as either required or optional) to its peers.
12 //! And the implementation can interpret a feature if the feature is known to it.
14 //! [BOLT #9]: https://github.com/lightningnetwork/lightning-rfc/blob/master/09-features.md
15 //! [messages]: ../msgs/index.html
16 //! [`Features`]: struct.Features.html
17 //! [`Context`]: sealed/trait.Context.html
20 use bitcoin::hashes::Hash;
21 use crate::c_types::*;
23 impl Clone for InitFeatures {
24 fn clone(&self) -> Self {
26 inner: if self.inner.is_null() { std::ptr::null_mut() } else {
27 Box::into_raw(Box::new(unsafe { &*self.inner }.clone())) },
33 /// Used only if an object of this type is returned as a trait impl by a method
34 pub(crate) extern "C" fn InitFeatures_clone_void(this_ptr: *const c_void) -> *mut c_void {
35 Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeInitFeatures)).clone() })) as *mut c_void
38 pub extern "C" fn InitFeatures_clone(orig: &InitFeatures) -> InitFeatures {
41 impl Clone for NodeFeatures {
42 fn clone(&self) -> Self {
44 inner: if self.inner.is_null() { std::ptr::null_mut() } else {
45 Box::into_raw(Box::new(unsafe { &*self.inner }.clone())) },
51 /// Used only if an object of this type is returned as a trait impl by a method
52 pub(crate) extern "C" fn NodeFeatures_clone_void(this_ptr: *const c_void) -> *mut c_void {
53 Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeNodeFeatures)).clone() })) as *mut c_void
56 pub extern "C" fn NodeFeatures_clone(orig: &NodeFeatures) -> NodeFeatures {
59 impl Clone for ChannelFeatures {
60 fn clone(&self) -> Self {
62 inner: if self.inner.is_null() { std::ptr::null_mut() } else {
63 Box::into_raw(Box::new(unsafe { &*self.inner }.clone())) },
69 /// Used only if an object of this type is returned as a trait impl by a method
70 pub(crate) extern "C" fn ChannelFeatures_clone_void(this_ptr: *const c_void) -> *mut c_void {
71 Box::into_raw(Box::new(unsafe { (*(this_ptr as *mut nativeChannelFeatures)).clone() })) as *mut c_void
74 pub extern "C" fn ChannelFeatures_clone(orig: &ChannelFeatures) -> ChannelFeatures {
78 use lightning::ln::features::InitFeatures as nativeInitFeaturesImport;
79 type nativeInitFeatures = nativeInitFeaturesImport;
81 /// Features used within an `init` message.
84 pub struct InitFeatures {
85 /// Nearly everywhere, inner must be non-null, however in places where
86 /// the Rust equivalent takes an Option, it may be set to null to indicate None.
87 pub inner: *mut nativeInitFeatures,
91 impl Drop for InitFeatures {
93 if self.is_owned && !self.inner.is_null() {
94 let _ = unsafe { Box::from_raw(self.inner) };
99 pub extern "C" fn InitFeatures_free(this_ptr: InitFeatures) { }
101 /// Used only if an object of this type is returned as a trait impl by a method
102 extern "C" fn InitFeatures_free_void(this_ptr: *mut c_void) {
103 unsafe { let _ = Box::from_raw(this_ptr as *mut nativeInitFeatures); }
106 /// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
108 pub(crate) fn take_inner(mut self) -> *mut nativeInitFeatures {
109 assert!(self.is_owned);
110 let ret = self.inner;
111 self.inner = std::ptr::null_mut();
116 use lightning::ln::features::NodeFeatures as nativeNodeFeaturesImport;
117 type nativeNodeFeatures = nativeNodeFeaturesImport;
119 /// Features used within a `node_announcement` message.
122 pub struct NodeFeatures {
123 /// Nearly everywhere, inner must be non-null, however in places where
124 /// the Rust equivalent takes an Option, it may be set to null to indicate None.
125 pub inner: *mut nativeNodeFeatures,
129 impl Drop for NodeFeatures {
131 if self.is_owned && !self.inner.is_null() {
132 let _ = unsafe { Box::from_raw(self.inner) };
137 pub extern "C" fn NodeFeatures_free(this_ptr: NodeFeatures) { }
139 /// Used only if an object of this type is returned as a trait impl by a method
140 extern "C" fn NodeFeatures_free_void(this_ptr: *mut c_void) {
141 unsafe { let _ = Box::from_raw(this_ptr as *mut nativeNodeFeatures); }
144 /// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
146 pub(crate) fn take_inner(mut self) -> *mut nativeNodeFeatures {
147 assert!(self.is_owned);
148 let ret = self.inner;
149 self.inner = std::ptr::null_mut();
154 use lightning::ln::features::ChannelFeatures as nativeChannelFeaturesImport;
155 type nativeChannelFeatures = nativeChannelFeaturesImport;
157 /// Features used within a `channel_announcement` message.
160 pub struct ChannelFeatures {
161 /// Nearly everywhere, inner must be non-null, however in places where
162 /// the Rust equivalent takes an Option, it may be set to null to indicate None.
163 pub inner: *mut nativeChannelFeatures,
167 impl Drop for ChannelFeatures {
169 if self.is_owned && !self.inner.is_null() {
170 let _ = unsafe { Box::from_raw(self.inner) };
175 pub extern "C" fn ChannelFeatures_free(this_ptr: ChannelFeatures) { }
177 /// Used only if an object of this type is returned as a trait impl by a method
178 extern "C" fn ChannelFeatures_free_void(this_ptr: *mut c_void) {
179 unsafe { let _ = Box::from_raw(this_ptr as *mut nativeChannelFeatures); }
182 /// When moving out of the pointer, we have to ensure we aren't a reference, this makes that easy
183 impl ChannelFeatures {
184 pub(crate) fn take_inner(mut self) -> *mut nativeChannelFeatures {
185 assert!(self.is_owned);
186 let ret = self.inner;
187 self.inner = std::ptr::null_mut();
191 /// Create a blank Features with no features set
194 pub extern "C" fn InitFeatures_empty() -> InitFeatures {
195 let mut ret = lightning::ln::features::InitFeatures::empty();
196 InitFeatures { inner: Box::into_raw(Box::new(ret)), is_owned: true }
199 /// Creates features known by the implementation as defined by [`T::KNOWN_FEATURE_FLAGS`].
201 /// [`T::KNOWN_FEATURE_FLAGS`]: sealed/trait.Context.html#associatedconstant.KNOWN_FEATURE_FLAGS
204 pub extern "C" fn InitFeatures_known() -> InitFeatures {
205 let mut ret = lightning::ln::features::InitFeatures::known();
206 InitFeatures { inner: Box::into_raw(Box::new(ret)), is_owned: true }
209 /// Create a blank Features with no features set
212 pub extern "C" fn NodeFeatures_empty() -> NodeFeatures {
213 let mut ret = lightning::ln::features::NodeFeatures::empty();
214 NodeFeatures { inner: Box::into_raw(Box::new(ret)), is_owned: true }
217 /// Creates features known by the implementation as defined by [`T::KNOWN_FEATURE_FLAGS`].
219 /// [`T::KNOWN_FEATURE_FLAGS`]: sealed/trait.Context.html#associatedconstant.KNOWN_FEATURE_FLAGS
222 pub extern "C" fn NodeFeatures_known() -> NodeFeatures {
223 let mut ret = lightning::ln::features::NodeFeatures::known();
224 NodeFeatures { inner: Box::into_raw(Box::new(ret)), is_owned: true }
227 /// Create a blank Features with no features set
230 pub extern "C" fn ChannelFeatures_empty() -> ChannelFeatures {
231 let mut ret = lightning::ln::features::ChannelFeatures::empty();
232 ChannelFeatures { inner: Box::into_raw(Box::new(ret)), is_owned: true }
235 /// Creates features known by the implementation as defined by [`T::KNOWN_FEATURE_FLAGS`].
237 /// [`T::KNOWN_FEATURE_FLAGS`]: sealed/trait.Context.html#associatedconstant.KNOWN_FEATURE_FLAGS
240 pub extern "C" fn ChannelFeatures_known() -> ChannelFeatures {
241 let mut ret = lightning::ln::features::ChannelFeatures::known();
242 ChannelFeatures { inner: Box::into_raw(Box::new(ret)), is_owned: true }
246 pub extern "C" fn InitFeatures_write(obj: &InitFeatures) -> crate::c_types::derived::CVec_u8Z {
247 crate::c_types::serialize_obj(unsafe { &*unsafe { &*obj }.inner })
250 pub(crate) extern "C" fn InitFeatures_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z {
251 crate::c_types::serialize_obj(unsafe { &*(obj as *const nativeInitFeatures) })
254 pub extern "C" fn NodeFeatures_write(obj: &NodeFeatures) -> crate::c_types::derived::CVec_u8Z {
255 crate::c_types::serialize_obj(unsafe { &*unsafe { &*obj }.inner })
258 pub(crate) extern "C" fn NodeFeatures_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z {
259 crate::c_types::serialize_obj(unsafe { &*(obj as *const nativeNodeFeatures) })
262 pub extern "C" fn ChannelFeatures_write(obj: &ChannelFeatures) -> crate::c_types::derived::CVec_u8Z {
263 crate::c_types::serialize_obj(unsafe { &*unsafe { &*obj }.inner })
266 pub(crate) extern "C" fn ChannelFeatures_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z {
267 crate::c_types::serialize_obj(unsafe { &*(obj as *const nativeChannelFeatures) })
270 pub extern "C" fn InitFeatures_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_InitFeaturesDecodeErrorZ {
271 let res = crate::c_types::deserialize_obj(ser);
272 let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::ln::features::InitFeatures { inner: Box::into_raw(Box::new(o)), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() };
276 pub extern "C" fn NodeFeatures_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_NodeFeaturesDecodeErrorZ {
277 let res = crate::c_types::deserialize_obj(ser);
278 let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::ln::features::NodeFeatures { inner: Box::into_raw(Box::new(o)), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() };
282 pub extern "C" fn ChannelFeatures_read(ser: crate::c_types::u8slice) -> crate::c_types::derived::CResult_ChannelFeaturesDecodeErrorZ {
283 let res = crate::c_types::deserialize_obj(ser);
284 let mut local_res = match res { Ok(mut o) => crate::c_types::CResultTempl::ok( { crate::ln::features::ChannelFeatures { inner: Box::into_raw(Box::new(o)), is_owned: true } }).into(), Err(mut e) => crate::c_types::CResultTempl::err( { crate::ln::msgs::DecodeError { inner: Box::into_raw(Box::new(e)), is_owned: true } }).into() };