Skip to content

Commit 26fae5e

Browse files
committed
Sanity check that known features are not required
1 parent 63d7f0d commit 26fae5e

File tree

1 file changed

+39
-2
lines changed

1 file changed

+39
-2
lines changed

lightning/src/ln/features.rs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,13 @@ mod sealed {
166166
/// [`BYTE_OFFSET`]: #associatedconstant.BYTE_OFFSET
167167
const OPTIONAL_MASK: u8 = 1 << (Self::ODD_BIT - 8 * Self::BYTE_OFFSET);
168168

169+
/// Returns whether the feature is required by the given flags.
170+
#[inline]
171+
fn requires_feature(flags: &Vec<u8>) -> bool {
172+
flags.len() > Self::BYTE_OFFSET &&
173+
(flags[Self::BYTE_OFFSET] & Self::REQUIRED_MASK) != 0
174+
}
175+
169176
/// Returns whether the feature is supported by the given flags.
170177
#[inline]
171178
fn supports_feature(flags: &Vec<u8>) -> bool {
@@ -429,12 +436,20 @@ impl<T: sealed::Context> Features<T> {
429436
}
430437

431438
impl<T: sealed::DataLossProtect> Features<T> {
439+
#[cfg(test)]
440+
pub(crate) fn requires_data_loss_protect(&self) -> bool {
441+
<T as sealed::DataLossProtect>::requires_feature(&self.flags)
442+
}
432443
pub(crate) fn supports_data_loss_protect(&self) -> bool {
433444
<T as sealed::DataLossProtect>::supports_feature(&self.flags)
434445
}
435446
}
436447

437448
impl<T: sealed::UpfrontShutdownScript> Features<T> {
449+
#[cfg(test)]
450+
pub(crate) fn requires_upfront_shutdown_script(&self) -> bool {
451+
<T as sealed::UpfrontShutdownScript>::requires_feature(&self.flags)
452+
}
438453
pub(crate) fn supports_upfront_shutdown_script(&self) -> bool {
439454
<T as sealed::UpfrontShutdownScript>::supports_feature(&self.flags)
440455
}
@@ -446,6 +461,10 @@ impl<T: sealed::UpfrontShutdownScript> Features<T> {
446461
}
447462

448463
impl<T: sealed::VariableLengthOnion> Features<T> {
464+
#[cfg(test)]
465+
pub(crate) fn requires_variable_length_onion(&self) -> bool {
466+
<T as sealed::VariableLengthOnion>::requires_feature(&self.flags)
467+
}
449468
pub(crate) fn supports_variable_length_onion(&self) -> bool {
450469
<T as sealed::VariableLengthOnion>::supports_feature(&self.flags)
451470
}
@@ -461,16 +480,24 @@ impl<T: sealed::InitialRoutingSync> Features<T> {
461480
}
462481

463482
impl<T: sealed::PaymentSecret> Features<T> {
464-
#[allow(dead_code)]
483+
#[cfg(test)]
484+
pub(crate) fn requires_payment_secret(&self) -> bool {
485+
<T as sealed::PaymentSecret>::requires_feature(&self.flags)
486+
}
465487
// Note that we never need to test this since what really matters is the invoice - iff the
466488
// invoice provides a payment_secret, we assume that we can use it (ie that the recipient
467489
// supports payment_secret).
490+
#[allow(dead_code)]
468491
pub(crate) fn supports_payment_secret(&self) -> bool {
469492
<T as sealed::PaymentSecret>::supports_feature(&self.flags)
470493
}
471494
}
472495

473496
impl<T: sealed::BasicMPP> Features<T> {
497+
#[cfg(test)]
498+
pub(crate) fn requires_basic_mpp(&self) -> bool {
499+
<T as sealed::BasicMPP>::requires_feature(&self.flags)
500+
}
474501
// We currently never test for this since we don't actually *generate* multipath routes.
475502
#[allow(dead_code)]
476503
pub(crate) fn supports_basic_mpp(&self) -> bool {
@@ -505,7 +532,7 @@ mod tests {
505532
use super::{ChannelFeatures, InitFeatures, NodeFeatures};
506533

507534
#[test]
508-
fn sanity_test_our_features() {
535+
fn sanity_test_known_features() {
509536
assert!(!ChannelFeatures::known().requires_unknown_bits());
510537
assert!(!ChannelFeatures::known().supports_unknown_bits());
511538
assert!(!InitFeatures::known().requires_unknown_bits());
@@ -515,18 +542,28 @@ mod tests {
515542

516543
assert!(InitFeatures::known().supports_upfront_shutdown_script());
517544
assert!(NodeFeatures::known().supports_upfront_shutdown_script());
545+
assert!(!InitFeatures::known().requires_upfront_shutdown_script());
546+
assert!(!NodeFeatures::known().requires_upfront_shutdown_script());
518547

519548
assert!(InitFeatures::known().supports_data_loss_protect());
520549
assert!(NodeFeatures::known().supports_data_loss_protect());
550+
assert!(!InitFeatures::known().requires_data_loss_protect());
551+
assert!(!NodeFeatures::known().requires_data_loss_protect());
521552

522553
assert!(InitFeatures::known().supports_variable_length_onion());
523554
assert!(NodeFeatures::known().supports_variable_length_onion());
555+
assert!(!InitFeatures::known().requires_variable_length_onion());
556+
assert!(!NodeFeatures::known().requires_variable_length_onion());
524557

525558
assert!(InitFeatures::known().supports_payment_secret());
526559
assert!(NodeFeatures::known().supports_payment_secret());
560+
assert!(!InitFeatures::known().requires_payment_secret());
561+
assert!(!NodeFeatures::known().requires_payment_secret());
527562

528563
assert!(InitFeatures::known().supports_basic_mpp());
529564
assert!(NodeFeatures::known().supports_basic_mpp());
565+
assert!(!InitFeatures::known().requires_basic_mpp());
566+
assert!(!NodeFeatures::known().requires_basic_mpp());
530567

531568
let mut init_features = InitFeatures::known();
532569
assert!(init_features.initial_routing_sync());

0 commit comments

Comments
 (0)