//! (see [BOLT-4](https://github.com/lightning/bolts/blob/master/04-onion-routing.md) for more information).
//! - `BasicMPP` - requires/supports that a node can receive basic multi-part payments
//! (see [BOLT-4](https://github.com/lightning/bolts/blob/master/04-onion-routing.md#basic-multi-part-payments) for more information).
+//! - `Wumbo` - requires/supports that a node create large channels. Called `option_support_large_channel` in the spec.
+//! (see [BOLT-2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-open_channel-message) for more information).
//! - `ShutdownAnySegwit` - requires/supports that future segwit versions are allowed in `shutdown`
//! (see [BOLT-2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md) for more information).
+//! - `OnionMessages` - requires/supports forwarding onion messages
+//! (see [BOLT-7](https://github.com/lightning/bolts/pull/759/files) for more information).
+//! TODO: update link
//! - `ChannelType` - node supports the channel_type field in open/accept
//! (see [BOLT-2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md) for more information).
//! - `SCIDPrivacy` - supply channel aliases for routing
// Byte 3
ShutdownAnySegwit,
// Byte 4
- ,
+ OnionMessages,
// Byte 5
ChannelType | SCIDPrivacy,
// Byte 6
// Byte 3
ShutdownAnySegwit,
// Byte 4
- ,
+ OnionMessages,
// Byte 5
ChannelType | SCIDPrivacy,
// Byte 6
define_feature!(27, ShutdownAnySegwit, [InitContext, NodeContext],
"Feature flags for `opt_shutdown_anysegwit`.", set_shutdown_any_segwit_optional,
set_shutdown_any_segwit_required, supports_shutdown_anysegwit, requires_shutdown_anysegwit);
+ define_feature!(39, OnionMessages, [InitContext, NodeContext],
+ "Feature flags for `option_onion_messages`.", set_onion_messages_optional,
+ set_onion_messages_required, supports_onion_messages, requires_onion_messages);
define_feature!(45, ChannelType, [InitContext, NodeContext],
"Feature flags for `option_channel_type`.", set_channel_type_optional,
set_channel_type_required, supports_channel_type, requires_channel_type);
mark: PhantomData<T>,
}
+impl <T: sealed::Context> Features<T> {
+ pub(crate) fn or(mut self, o: Self) -> Self {
+ let total_feature_len = cmp::max(self.flags.len(), o.flags.len());
+ self.flags.resize(total_feature_len, 0u8);
+ for (byte, o_byte) in self.flags.iter_mut().zip(o.flags.iter()) {
+ *byte |= *o_byte;
+ }
+ self
+ }
+}
+
impl<T: sealed::Context> Clone for Features<T> {
fn clone(&self) -> Self {
Self {
Ok(())
}
- /// or's another InitFeatures into this one.
- pub(crate) fn or(mut self, o: InitFeatures) -> InitFeatures {
- let total_feature_len = cmp::max(self.flags.len(), o.flags.len());
- self.flags.resize(total_feature_len, 0u8);
- for (byte, o_byte) in self.flags.iter_mut().zip(o.flags.iter()) {
- *byte |= *o_byte;
- }
- self
- }
-
/// Converts `InitFeatures` to `Features<C>`. Only known `InitFeatures` relevant to context `C`
/// are included in the result.
pub(crate) fn to_context<C: sealed::Context>(&self) -> Features<C> {
}
impl<T: sealed::InitialRoutingSync> Features<T> {
- // We are no longer setting initial_routing_sync now that gossip_queries
- // is enabled. This feature is ignored by a peer when gossip_queries has
- // been negotiated.
+ // Note that initial_routing_sync is ignored if gossip_queries is set.
#[cfg(test)]
- pub(crate) fn clear_initial_routing_sync(&mut self) {
- <T as sealed::InitialRoutingSync>::clear_bits(&mut self.flags)
+ pub(crate) fn clear_initial_routing_sync(mut self) -> Self {
+ <T as sealed::InitialRoutingSync>::clear_bits(&mut self.flags);
+ self
}
}
assert!(!InitFeatures::known().requires_wumbo());
assert!(!NodeFeatures::known().requires_wumbo());
+ assert!(InitFeatures::known().supports_onion_messages());
+ assert!(NodeFeatures::known().supports_onion_messages());
+ assert!(!InitFeatures::known().requires_onion_messages());
+ assert!(!NodeFeatures::known().requires_onion_messages());
+
assert!(InitFeatures::known().supports_zero_conf());
assert!(!InitFeatures::known().requires_zero_conf());
assert!(NodeFeatures::known().supports_zero_conf());
let mut init_features = InitFeatures::known();
assert!(init_features.initial_routing_sync());
- init_features.clear_initial_routing_sync();
+ init_features = init_features.clear_initial_routing_sync();
assert!(!init_features.initial_routing_sync());
}
// - var_onion_optin (req) | static_remote_key (req) | payment_secret(req)
// - basic_mpp | wumbo
// - opt_shutdown_anysegwit
- // -
+ // - onion_messages
// - option_channel_type | option_scid_alias
// - option_zeroconf
assert_eq!(node_features.flags.len(), 7);
assert_eq!(node_features.flags[1], 0b01010001);
assert_eq!(node_features.flags[2], 0b00001010);
assert_eq!(node_features.flags[3], 0b00001000);
- assert_eq!(node_features.flags[4], 0b00000000);
+ assert_eq!(node_features.flags[4], 0b10000000);
assert_eq!(node_features.flags[5], 0b10100000);
assert_eq!(node_features.flags[6], 0b00001000);
}