X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffeatures.rs;h=9509f0f23bf6e1c5e7a5d0c66da2a7e3c8bdc58b;hb=32b5d843d975fe2a0b8efd0d3d370903c89eeeb5;hp=2580874640e438e611bea9b88ddda0384dc9db5d;hpb=132b07239784749dcadfc2959a9487107789df56;p=rust-lightning diff --git a/lightning/src/ln/features.rs b/lightning/src/ln/features.rs index 25808746..9509f0f2 100644 --- a/lightning/src/ln/features.rs +++ b/lightning/src/ln/features.rs @@ -19,7 +19,41 @@ //! supports a feature if it advertises the feature (as either required or optional) to its peers. //! And the implementation can interpret a feature if the feature is known to it. //! -//! [BOLT #9]: https://github.com/lightningnetwork/lightning-rfc/blob/master/09-features.md +//! The following features are currently required in the LDK: +//! - `VariableLengthOnion` - requires/supports variable-length routing onion payloads +//! (see [BOLT-4](https://github.com/lightning/bolts/blob/master/04-onion-routing.md) for more information). +//! - `StaticRemoteKey` - requires/supports static key for remote output +//! (see [BOLT-3](https://github.com/lightning/bolts/blob/master/03-transactions.md) for more information). +//! +//! The following features are currently supported in the LDK: +//! - `DataLossProtect` - requires/supports that a node which has somehow fallen behind, e.g., has been restored from an old backup, +//! can detect that it has fallen behind +//! (see [BOLT-2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md) for more information). +//! - `InitialRoutingSync` - requires/supports that the sending node needs a complete routing information dump +//! (see [BOLT-7](https://github.com/lightning/bolts/blob/master/07-routing-gossip.md#initial-sync) for more information). +//! - `UpfrontShutdownScript` - commits to a shutdown scriptpubkey when opening a channel +//! (see [BOLT-2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md#the-open_channel-message) for more information). +//! - `GossipQueries` - requires/supports more sophisticated gossip control +//! (see [BOLT-7](https://github.com/lightning/bolts/blob/master/07-routing-gossip.md) for more information). +//! - `PaymentSecret` - requires/supports that a node supports payment_secret field +//! (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 +//! (see [BOLT-2](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md) for more information). +//! - `Keysend` - send funds to a node without an invoice +//! (see the [`Keysend` feature assignment proposal](https://github.com/lightning/bolts/issues/605#issuecomment-606679798) for more information). +//! +//! [BOLT #9]: https://github.com/lightning/bolts/blob/master/09-features.md //! [messages]: crate::ln::msgs use {io, io_extras}; @@ -130,6 +164,8 @@ mod sealed { , // Byte 5 , + // Byte 6 + , ], optional_features: [ // Byte 0 @@ -141,9 +177,11 @@ mod sealed { // Byte 3 ShutdownAnySegwit, // Byte 4 - , + OnionMessages, // Byte 5 ChannelType | SCIDPrivacy, + // Byte 6 + ZeroConf, ], }); define_context!(NodeContext { @@ -173,11 +211,11 @@ mod sealed { // Byte 3 ShutdownAnySegwit, // Byte 4 - , + OnionMessages, // Byte 5 ChannelType | SCIDPrivacy, // Byte 6 - Keysend, + ZeroConf | Keysend, ], }); define_context!(ChannelContext { @@ -218,6 +256,8 @@ mod sealed { , // Byte 5 SCIDPrivacy, + // Byte 6 + ZeroConf, ], optional_features: [ // Byte 0 @@ -232,6 +272,8 @@ mod sealed { , // Byte 5 , + // Byte 6 + , ], }); @@ -244,7 +286,7 @@ mod sealed { /// /// See [BOLT #9] for details. /// - /// [BOLT #9]: https://github.com/lightningnetwork/lightning-rfc/blob/master/09-features.md + /// [BOLT #9]: https://github.com/lightning/bolts/blob/master/09-features.md pub trait $feature: Context { /// The bit used to signify that the feature is required. const EVEN_BIT: usize = $odd_bit - 1; @@ -396,13 +438,18 @@ mod sealed { 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); define_feature!(47, SCIDPrivacy, [InitContext, NodeContext, ChannelTypeContext], "Feature flags for only forwarding with SCID aliasing. Called `option_scid_alias` in the BOLTs", set_scid_privacy_optional, set_scid_privacy_required, supports_scid_privacy, requires_scid_privacy); - + define_feature!(51, ZeroConf, [InitContext, NodeContext, ChannelTypeContext], + "Feature flags for accepting channels with zero confirmations. Called `option_zeroconf` in the BOLTs", + set_zero_conf_optional, set_zero_conf_required, supports_zero_conf, requires_zero_conf); define_feature!(55, Keysend, [NodeContext], "Feature flags for keysend payments.", set_keysend_optional, set_keysend_required, supports_keysend, requires_keysend); @@ -424,6 +471,17 @@ pub struct Features { mark: PhantomData, } +impl Features { + 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 Clone for Features { fn clone(&self) -> Self { Self { @@ -486,16 +544,6 @@ impl InitFeatures { 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`. Only known `InitFeatures` relevant to context `C` /// are included in the result. pub(crate) fn to_context(&self) -> Features { @@ -727,12 +775,11 @@ impl Features { } impl Features { - // 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) { - ::clear_bits(&mut self.flags) + pub(crate) fn clear_initial_routing_sync(mut self) -> Self { + ::clear_bits(&mut self.flags); + self } } @@ -852,17 +899,31 @@ mod tests { assert!(InitFeatures::known().supports_scid_privacy()); assert!(NodeFeatures::known().supports_scid_privacy()); + assert!(ChannelTypeFeatures::known().supports_scid_privacy()); assert!(!InitFeatures::known().requires_scid_privacy()); assert!(!NodeFeatures::known().requires_scid_privacy()); + assert!(ChannelTypeFeatures::known().requires_scid_privacy()); assert!(InitFeatures::known().supports_wumbo()); assert!(NodeFeatures::known().supports_wumbo()); 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()); + assert!(!NodeFeatures::known().requires_zero_conf()); + assert!(ChannelTypeFeatures::known().supports_zero_conf()); + assert!(ChannelTypeFeatures::known().requires_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()); } @@ -897,15 +958,17 @@ mod tests { // - 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 - assert_eq!(node_features.flags.len(), 6); + // - option_zeroconf + assert_eq!(node_features.flags.len(), 7); assert_eq!(node_features.flags[0], 0b00000010); 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); } // Check that cleared flags are kept blank when converting back: