Document nonzero anchors in features module.
[rust-lightning] / lightning / src / ln / features.rs
index 71bb66bacf7bc84380fe49316d9acec5ea293dff..400888ff9784ff0f8217de151f5b4f24d23509a7 100644 (file)
 //!     [BOLT-3](https://github.com/lightning/bolts/blob/master/03-transactions.md) for more
 //!     information).
 //!
+//! LDK knows about the following features, but does not support them:
+//! - `AnchorsNonzeroFeeHtlcTx` - the initial version of anchor outputs, which was later found to be
+//!     vulnerable (see this
+//!     [mailing list post](https://lists.linuxfoundation.org/pipermail/lightning-dev/2020-September/002796.html)
+//!     for more information).
+//!
 //! [BOLT #9]: https://github.com/lightning/bolts/blob/master/09-features.md
 //! [messages]: crate::ln::msgs
 
@@ -134,7 +140,7 @@ mod sealed {
                // Byte 1
                VariableLengthOnion | StaticRemoteKey | PaymentSecret,
                // Byte 2
-               BasicMPP | Wumbo | AnchorsZeroFeeHtlcTx,
+               BasicMPP | Wumbo | AnchorsNonzeroFeeHtlcTx | AnchorsZeroFeeHtlcTx,
                // Byte 3
                ShutdownAnySegwit,
                // Byte 4
@@ -150,7 +156,7 @@ mod sealed {
                // Byte 1
                VariableLengthOnion | StaticRemoteKey | PaymentSecret,
                // Byte 2
-               BasicMPP | Wumbo | AnchorsZeroFeeHtlcTx,
+               BasicMPP | Wumbo | AnchorsNonzeroFeeHtlcTx | AnchorsZeroFeeHtlcTx,
                // Byte 3
                ShutdownAnySegwit,
                // Byte 4
@@ -196,7 +202,7 @@ mod sealed {
                // Byte 1
                StaticRemoteKey,
                // Byte 2
-               AnchorsZeroFeeHtlcTx,
+               AnchorsNonzeroFeeHtlcTx | AnchorsZeroFeeHtlcTx,
                // Byte 3
                ,
                // Byte 4
@@ -378,6 +384,9 @@ mod sealed {
        define_feature!(19, Wumbo, [InitContext, NodeContext],
                "Feature flags for `option_support_large_channel` (aka wumbo channels).", set_wumbo_optional, set_wumbo_required,
                supports_wumbo, requires_wumbo);
+       define_feature!(21, AnchorsNonzeroFeeHtlcTx, [InitContext, NodeContext, ChannelTypeContext],
+               "Feature flags for `option_anchors_nonzero_fee_htlc_tx`.", set_anchors_nonzero_fee_htlc_tx_optional,
+               set_anchors_nonzero_fee_htlc_tx_required, supports_anchors_nonzero_fee_htlc_tx, requires_anchors_nonzero_fee_htlc_tx);
        define_feature!(23, AnchorsZeroFeeHtlcTx, [InitContext, NodeContext, ChannelTypeContext],
                "Feature flags for `option_anchors_zero_fee_htlc_tx`.", set_anchors_zero_fee_htlc_tx_optional,
                set_anchors_zero_fee_htlc_tx_required, supports_anchors_zero_fee_htlc_tx, requires_anchors_zero_fee_htlc_tx);
@@ -453,6 +462,16 @@ impl<T: sealed::Context> PartialEq for Features<T> {
                self.flags.eq(&o.flags)
        }
 }
+impl<T: sealed::Context> PartialOrd for Features<T> {
+       fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
+               self.flags.partial_cmp(&other.flags)
+       }
+}
+impl<T: sealed::Context + Eq> Ord for Features<T> {
+       fn cmp(&self, other: &Self) -> cmp::Ordering {
+               self.flags.cmp(&other.flags)
+       }
+}
 impl<T: sealed::Context> fmt::Debug for Features<T> {
        fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
                self.flags.fmt(fmt)
@@ -525,15 +544,29 @@ impl InvoiceFeatures {
        /// [`PaymentParameters::for_keysend`], thus omitting the need for payers to manually construct an
        /// `InvoiceFeatures` for [`find_route`].
        ///
+       /// MPP keysend is not widely supported yet, so we parameterize support to allow the user to
+       /// choose whether their router should find multi-part routes.
+       ///
        /// [`PaymentParameters::for_keysend`]: crate::routing::router::PaymentParameters::for_keysend
        /// [`find_route`]: crate::routing::router::find_route
-       pub(crate) fn for_keysend() -> InvoiceFeatures {
+       pub(crate) fn for_keysend(allow_mpp: bool) -> InvoiceFeatures {
                let mut res = InvoiceFeatures::empty();
                res.set_variable_length_onion_optional();
+               if allow_mpp {
+                       res.set_basic_mpp_optional();
+               }
                res
        }
 }
 
+impl Bolt12InvoiceFeatures {
+       /// Converts `Bolt12InvoiceFeatures` to `Features<C>`. Only known `Bolt12InvoiceFeatures` relevant
+       /// to context `C` are included in the result.
+       pub(crate) fn to_context<C: sealed::Context>(&self) -> Features<C> {
+               self.to_context_internal()
+       }
+}
+
 impl ChannelTypeFeatures {
        // Maps the relevant `InitFeatures` to `ChannelTypeFeatures`. Any unknown features to
        // `ChannelTypeFeatures` are not included in the result.
@@ -856,6 +889,7 @@ impl_feature_len_prefixed_write!(InitFeatures);
 impl_feature_len_prefixed_write!(ChannelFeatures);
 impl_feature_len_prefixed_write!(NodeFeatures);
 impl_feature_len_prefixed_write!(InvoiceFeatures);
+impl_feature_len_prefixed_write!(Bolt12InvoiceFeatures);
 impl_feature_len_prefixed_write!(BlindedHopFeatures);
 
 // Some features only appear inside of TLVs, so they don't have a length prefix when serialized.
@@ -964,12 +998,12 @@ mod tests {
                init_features.set_payment_secret_required();
                init_features.set_basic_mpp_optional();
                init_features.set_wumbo_optional();
+               init_features.set_anchors_zero_fee_htlc_tx_optional();
                init_features.set_shutdown_any_segwit_optional();
                init_features.set_onion_messages_optional();
                init_features.set_channel_type_optional();
                init_features.set_scid_privacy_optional();
                init_features.set_zero_conf_optional();
-               init_features.set_anchors_zero_fee_htlc_tx_optional();
 
                assert!(init_features.initial_routing_sync());
                assert!(!init_features.supports_upfront_shutdown_script());
@@ -980,7 +1014,7 @@ mod tests {
                        // Check that the flags are as expected:
                        // - option_data_loss_protect (req)
                        // - var_onion_optin (req) | static_remote_key (req) | payment_secret(req)
-                       // - basic_mpp | wumbo
+                       // - basic_mpp | wumbo | anchors_zero_fee_htlc_tx
                        // - opt_shutdown_anysegwit
                        // - onion_messages
                        // - option_channel_type | option_scid_alias