//! for more info).
//! - `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).
+//! - `Trampoline` - supports receiving and forwarding Trampoline payments
+//! (see the [`Trampoline` feature proposal](https://github.com/lightning/bolts/pull/836) 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
//! [BOLT #9]: https://github.com/lightning/bolts/blob/master/09-features.md
//! [messages]: crate::ln::msgs
-use crate::{io, io_extras};
+#[allow(unused_imports)]
use crate::prelude::*;
+
+use crate::{io, io_extras};
use core::{cmp, fmt};
use core::borrow::Borrow;
use core::hash::{Hash, Hasher};
use core::marker::PhantomData;
-use bitcoin::bech32;
-use bitcoin::bech32::{Base32Len, FromBase32, ToBase32, u5, WriteBase32};
+use bech32::{Base32Len, FromBase32, ToBase32, u5, WriteBase32};
use crate::ln::msgs::DecodeError;
use crate::util::ser::{Readable, WithoutLength, Writeable, Writer};
mod sealed {
+ #[allow(unused_imports)]
use crate::prelude::*;
use crate::ln::features::Features;
ChannelType | SCIDPrivacy,
// Byte 6
ZeroConf,
+ // Byte 7
+ Trampoline,
]);
define_context!(NodeContext, [
// Byte 0
ChannelType | SCIDPrivacy,
// Byte 6
ZeroConf | Keysend,
+ // Byte 7
+ Trampoline,
]);
define_context!(ChannelContext, []);
define_context!(Bolt11InvoiceContext, [
,
// Byte 6
PaymentMetadata,
+ // Byte 7
+ Trampoline,
]);
define_context!(OfferContext, []);
define_context!(InvoiceRequestContext, []);
define_feature!(55, Keysend, [NodeContext],
"Feature flags for keysend payments.", set_keysend_optional, set_keysend_required,
supports_keysend, requires_keysend);
+ define_feature!(57, Trampoline, [InitContext, NodeContext, Bolt11InvoiceContext],
+ "Feature flags for Trampoline routing.", set_trampoline_routing_optional, set_trampoline_routing_required,
+ supports_trampoline_routing, requires_trampoline_routing);
// Note: update the module-level docs when a new feature bit is added!
#[cfg(test)]
set_unknown_feature_required, supports_unknown_test_feature, requires_unknown_test_feature);
}
+const ANY_REQUIRED_FEATURES_MASK: u8 = 0b01_01_01_01;
+const ANY_OPTIONAL_FEATURES_MASK: u8 = 0b10_10_10_10;
+
/// Tracks the set of features which a node implements, templated by the context in which it
/// appears.
///
// ChannelTypeFeatures must only contain required bits, so we OR the required forms of all
// optional bits and then AND out the optional ones.
for byte in ret.flags.iter_mut() {
- *byte |= (*byte & 0b10_10_10_10) >> 1;
- *byte &= 0b01_01_01_01;
+ *byte |= (*byte & ANY_OPTIONAL_FEATURES_MASK) >> 1;
+ *byte &= ANY_REQUIRED_FEATURES_MASK;
}
ret
}
}
pub(crate) fn supports_any_optional_bits(&self) -> bool {
- self.flags.iter().any(|&byte| (byte & 0b10_10_10_10) != 0)
+ self.flags.iter().any(|&byte| (byte & ANY_OPTIONAL_FEATURES_MASK) != 0)
}
/// Returns true if this `Features` object contains required features unknown by `other`.
// Bitwise AND-ing with all even bits set except for known features will select required
// unknown features.
self.flags.iter().enumerate().any(|(i, &byte)| {
- const REQUIRED_FEATURES: u8 = 0b01_01_01_01;
- const OPTIONAL_FEATURES: u8 = 0b10_10_10_10;
- let unknown_features = if i < other.flags.len() {
- // Form a mask similar to !T::KNOWN_FEATURE_MASK only for `other`
- !(other.flags[i]
- | ((other.flags[i] >> 1) & REQUIRED_FEATURES)
- | ((other.flags[i] << 1) & OPTIONAL_FEATURES))
- } else {
- 0b11_11_11_11
- };
- (byte & (REQUIRED_FEATURES & unknown_features)) != 0
+ let unknown_features = unset_features_mask_at_position(other, i);
+ (byte & (ANY_REQUIRED_FEATURES_MASK & unknown_features)) != 0
})
}
+ pub(crate) fn required_unknown_bits_from(&self, other: &Self) -> Vec<usize> {
+ let mut unknown_bits = Vec::new();
+
+ // Bitwise AND-ing with all even bits set except for known features will select required
+ // unknown features.
+ self.flags.iter().enumerate().for_each(|(i, &byte)| {
+ let unknown_features = unset_features_mask_at_position(other, i);
+ if byte & unknown_features != 0 {
+ for bit in (0..8).step_by(2) {
+ if ((byte & unknown_features) >> bit) & 1 == 1 {
+ unknown_bits.push(i * 8 + bit);
+ }
+ }
+ }
+ });
+
+ unknown_bits
+ }
+
/// Returns true if this `Features` object contains unknown feature flags which are set as
/// "required".
pub fn requires_unknown_bits(&self) -> bool {
// unknown features.
let byte_count = T::KNOWN_FEATURE_MASK.len();
self.flags.iter().enumerate().any(|(i, &byte)| {
- let required_features = 0b01_01_01_01;
let unknown_features = if i < byte_count {
!T::KNOWN_FEATURE_MASK[i]
} else {
0b11_11_11_11
};
- (byte & (required_features & unknown_features)) != 0
+ (byte & (ANY_REQUIRED_FEATURES_MASK & unknown_features)) != 0
})
}
}
}
+pub(crate) fn unset_features_mask_at_position<T: sealed::Context>(other: &Features<T>, index: usize) -> u8 {
+ if index < other.flags.len() {
+ // Form a mask similar to !T::KNOWN_FEATURE_MASK only for `other`
+ !(other.flags[index]
+ | ((other.flags[index] >> 1) & ANY_REQUIRED_FEATURES_MASK)
+ | ((other.flags[index] << 1) & ANY_OPTIONAL_FEATURES_MASK))
+ } else {
+ 0b11_11_11_11
+ }
+}
+
#[cfg(test)]
mod tests {
use super::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, Bolt11InvoiceFeatures, NodeFeatures, OfferFeatures, sealed};
- use bitcoin::bech32::{Base32Len, FromBase32, ToBase32, u5};
+ use bech32::{Base32Len, FromBase32, ToBase32, u5};
use crate::util::ser::{Readable, WithoutLength, Writeable};
#[test]
features.set_unknown_feature_required();
assert!(features.requires_unknown_bits());
assert!(features.supports_unknown_bits());
+ assert_eq!(features.required_unknown_bits_from(&ChannelFeatures::empty()), vec![123456788]);
let mut features = ChannelFeatures::empty();
features.set_unknown_feature_optional();
assert!(!features.requires_unknown_bits());
assert!(features.supports_unknown_bits());
+ assert_eq!(features.required_unknown_bits_from(&ChannelFeatures::empty()), vec![]);
+
+ let mut features = ChannelFeatures::empty();
+ features.set_unknown_feature_required();
+ features.set_custom_bit(123456786).unwrap();
+ assert!(features.requires_unknown_bits());
+ assert!(features.supports_unknown_bits());
+ assert_eq!(features.required_unknown_bits_from(&ChannelFeatures::empty()), vec![123456786, 123456788]);
+
+ let mut limiter = ChannelFeatures::empty();
+ limiter.set_unknown_feature_optional();
+ assert_eq!(features.required_unknown_bits_from(&limiter), vec![123456786]);
}
#[test]