X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Ffeatures.rs;h=ca6ea70b61da7312de22b1e28749a51cb3f28941;hb=b66e3c53768f6bc7bc43064f1818051d22477c63;hp=b8087546c7445060230a5ad776a9b3f13c113d37;hpb=498f2331459d8031031ef151a44c90d700aa8c7e;p=rust-lightning diff --git a/lightning/src/ln/features.rs b/lightning/src/ln/features.rs index b8087546..ca6ea70b 100644 --- a/lightning/src/ln/features.rs +++ b/lightning/src/ln/features.rs @@ -65,12 +65,19 @@ //! [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 use crate::{io, io_extras}; use crate::prelude::*; use core::{cmp, fmt}; +use core::borrow::Borrow; use core::hash::{Hash, Hasher}; use core::marker::PhantomData; @@ -134,7 +141,7 @@ mod sealed { // Byte 1 VariableLengthOnion | StaticRemoteKey | PaymentSecret, // Byte 2 - BasicMPP | Wumbo | AnchorsZeroFeeHtlcTx, + BasicMPP | Wumbo | AnchorsNonzeroFeeHtlcTx | AnchorsZeroFeeHtlcTx, // Byte 3 ShutdownAnySegwit, // Byte 4 @@ -150,7 +157,7 @@ mod sealed { // Byte 1 VariableLengthOnion | StaticRemoteKey | PaymentSecret, // Byte 2 - BasicMPP | Wumbo | AnchorsZeroFeeHtlcTx, + BasicMPP | Wumbo | AnchorsNonzeroFeeHtlcTx | AnchorsZeroFeeHtlcTx, // Byte 3 ShutdownAnySegwit, // Byte 4 @@ -196,7 +203,7 @@ mod sealed { // Byte 1 StaticRemoteKey, // Byte 2 - AnchorsZeroFeeHtlcTx, + AnchorsNonzeroFeeHtlcTx | AnchorsZeroFeeHtlcTx, // Byte 3 , // Byte 4 @@ -378,6 +385,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); @@ -422,15 +432,21 @@ pub struct Features { mark: PhantomData, } +impl> core::ops::BitOrAssign for Features { + fn bitor_assign(&mut self, rhs: Rhs) { + let total_feature_len = cmp::max(self.flags.len(), rhs.borrow().flags.len()); + self.flags.resize(total_feature_len, 0u8); + for (byte, rhs_byte) in self.flags.iter_mut().zip(rhs.borrow().flags.iter()) { + *byte |= *rhs_byte; + } + } +} + impl core::ops::BitOr for Features { type Output = Self; fn bitor(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 |= o; self } } @@ -535,11 +551,17 @@ 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 } } @@ -572,6 +594,14 @@ impl ChannelTypeFeatures { ::set_required_bit(&mut ret.flags); ret } + + /// Constructs a ChannelTypeFeatures with anchors support + pub(crate) fn anchors_zero_htlc_fee_and_dependencies() -> Self { + let mut ret = Self::empty(); + ::set_required_bit(&mut ret.flags); + ::set_required_bit(&mut ret.flags); + ret + } } impl ToBase32 for InvoiceFeatures {