//! [BOLT #9]: https://github.com/lightningnetwork/lightning-rfc/blob/master/09-features.md
//! [messages]: crate::ln::msgs
-use std::{cmp, fmt};
-use std::marker::PhantomData;
+use prelude::*;
+use core::{cmp, fmt};
+use core::marker::PhantomData;
use bitcoin::bech32;
use bitcoin::bech32::{Base32Len, FromBase32, ToBase32, u5, WriteBase32};
use util::ser::{Readable, Writeable, Writer};
mod sealed {
+ use prelude::*;
use ln::features::Features;
/// The context in which [`Features`] are applicable. Defines which features are required and
// Byte 0
,
// Byte 1
- StaticRemoteKey,
+ VariableLengthOnion | StaticRemoteKey | PaymentSecret,
// Byte 2
,
// Byte 3
// Byte 0
DataLossProtect | InitialRoutingSync | UpfrontShutdownScript | GossipQueries,
// Byte 1
- VariableLengthOnion | PaymentSecret,
+ ,
// Byte 2
BasicMPP,
// Byte 3
// Byte 0
,
// Byte 1
- StaticRemoteKey,
+ VariableLengthOnion | StaticRemoteKey | PaymentSecret,
// Byte 2
,
// Byte 3
// Byte 0
DataLossProtect | UpfrontShutdownScript | GossipQueries,
// Byte 1
- VariableLengthOnion | PaymentSecret,
+ ,
// Byte 2
BasicMPP,
// Byte 3
optional_features: [],
});
define_context!(InvoiceContext {
- required_features: [,,,],
- optional_features: [
+ required_features: [
// Byte 0
,
// Byte 1
VariableLengthOnion | PaymentSecret,
// Byte 2
+ ,
+ ],
+ optional_features: [
+ // Byte 0
+ ,
+ // Byte 1
+ ,
+ // Byte 2
BasicMPP,
],
});
/// Create a Features given a set of flags, in little-endian. This is in reverse byte order from
/// most on-the-wire encodings.
+ /// (C-not exported) as we don't support export across multiple T
pub fn from_le_bytes(flags: Vec<u8>) -> Features<T> {
Features {
flags,
pub(crate) fn requires_payment_secret(&self) -> bool {
<T as sealed::PaymentSecret>::requires_feature(&self.flags)
}
- // Note that we never need to test this since what really matters is the invoice - iff the
- // invoice provides a payment_secret, we assume that we can use it (ie that the recipient
- // supports payment_secret).
- #[allow(dead_code)]
- pub(crate) fn supports_payment_secret(&self) -> bool {
+ /// Returns whether the `payment_secret` feature is supported.
+ pub fn supports_payment_secret(&self) -> bool {
<T as sealed::PaymentSecret>::supports_feature(&self.flags)
}
}
assert!(InitFeatures::known().supports_variable_length_onion());
assert!(NodeFeatures::known().supports_variable_length_onion());
- assert!(!InitFeatures::known().requires_variable_length_onion());
- assert!(!NodeFeatures::known().requires_variable_length_onion());
+ assert!(InvoiceFeatures::known().supports_variable_length_onion());
+ assert!(InitFeatures::known().requires_variable_length_onion());
+ assert!(NodeFeatures::known().requires_variable_length_onion());
+ assert!(InvoiceFeatures::known().requires_variable_length_onion());
assert!(InitFeatures::known().supports_static_remote_key());
assert!(NodeFeatures::known().supports_static_remote_key());
assert!(InitFeatures::known().supports_payment_secret());
assert!(NodeFeatures::known().supports_payment_secret());
- assert!(!InitFeatures::known().requires_payment_secret());
- assert!(!NodeFeatures::known().requires_payment_secret());
+ assert!(InvoiceFeatures::known().supports_payment_secret());
+ assert!(InitFeatures::known().requires_payment_secret());
+ assert!(NodeFeatures::known().requires_payment_secret());
+ assert!(InvoiceFeatures::known().requires_payment_secret());
assert!(InitFeatures::known().supports_basic_mpp());
assert!(NodeFeatures::known().supports_basic_mpp());
+ assert!(InvoiceFeatures::known().supports_basic_mpp());
assert!(!InitFeatures::known().requires_basic_mpp());
assert!(!NodeFeatures::known().requires_basic_mpp());
+ assert!(!InvoiceFeatures::known().requires_basic_mpp());
assert!(InitFeatures::known().supports_shutdown_anysegwit());
assert!(NodeFeatures::known().supports_shutdown_anysegwit());
{
// Check that the flags are as expected:
// - option_data_loss_protect
- // - var_onion_optin | static_remote_key (req) | payment_secret
+ // - var_onion_optin (req) | static_remote_key (req) | payment_secret(req)
// - basic_mpp
// - opt_shutdown_anysegwit
assert_eq!(node_features.flags.len(), 4);
assert_eq!(node_features.flags[0], 0b00000010);
- assert_eq!(node_features.flags[1], 0b10010010);
+ assert_eq!(node_features.flags[1], 0b01010001);
assert_eq!(node_features.flags[2], 0b00000010);
assert_eq!(node_features.flags[3], 0b00001000);
}