Skip to content

Commit 8a85be4

Browse files
committed
Offer features for BOLT 12
The offer message in BOLT 12 contains a features TLV record. Add a corresponding OfferFeatures type where the length is not included in the serialization as it would be redundant with the record length. Otherwise, define the features to be the same as InvoiceFeatures.
1 parent 990e346 commit 8a85be4

File tree

1 file changed

+28
-14
lines changed

1 file changed

+28
-14
lines changed

lightning/src/ln/features.rs

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,10 @@ mod sealed {
243243
BasicMPP,
244244
],
245245
});
246+
define_context!(OfferContext {
247+
required_features: [],
248+
optional_features: [],
249+
});
246250
// This isn't a "real" feature context, and is only used in the channel_type field in an
247251
// `OpenChannel` message.
248252
define_context!(ChannelTypeContext {
@@ -458,7 +462,7 @@ mod sealed {
458462
supports_keysend, requires_keysend);
459463

460464
#[cfg(test)]
461-
define_feature!(123456789, UnknownFeature, [NodeContext, ChannelContext, InvoiceContext],
465+
define_feature!(123456789, UnknownFeature, [NodeContext, ChannelContext, InvoiceContext, OfferContext],
462466
"Feature flags for an unknown feature used in testing.", set_unknown_feature_optional,
463467
set_unknown_feature_required, supports_unknown_test_feature, requires_unknown_test_feature);
464468
}
@@ -517,6 +521,8 @@ pub type NodeFeatures = Features<sealed::NodeContext>;
517521
pub type ChannelFeatures = Features<sealed::ChannelContext>;
518522
/// Features used within an invoice.
519523
pub type InvoiceFeatures = Features<sealed::InvoiceContext>;
524+
/// Features used within an offer.
525+
pub type OfferFeatures = Features<sealed::OfferContext>;
520526

521527
/// Features used within the channel_type field in an OpenChannel message.
522528
///
@@ -845,24 +851,29 @@ impl_feature_len_prefixed_write!(ChannelFeatures);
845851
impl_feature_len_prefixed_write!(NodeFeatures);
846852
impl_feature_len_prefixed_write!(InvoiceFeatures);
847853

848-
// Because ChannelTypeFeatures only appears inside of TLVs, it doesn't have a length prefix when
849-
// serialized. Thus, we can't use `impl_feature_len_prefixed_write`, above, and have to write our
850-
// own serialization.
851-
impl Writeable for ChannelTypeFeatures {
852-
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
853-
self.write_be(w)
854-
}
855-
}
856-
impl Readable for ChannelTypeFeatures {
857-
fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
858-
let v = io_extras::read_to_end(r)?;
859-
Ok(Self::from_be_bytes(v))
854+
// Some features only appear inside of TLVs, so they don't have a length prefix when serialized.
855+
macro_rules! impl_feature_tlv_write {
856+
($features: ident) => {
857+
impl Writeable for $features {
858+
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
859+
self.write_be(w)
860+
}
861+
}
862+
impl Readable for $features {
863+
fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
864+
let v = io_extras::read_to_end(r)?;
865+
Ok(Self::from_be_bytes(v))
866+
}
867+
}
860868
}
861869
}
862870

871+
impl_feature_tlv_write!(ChannelTypeFeatures);
872+
impl_feature_tlv_write!(OfferFeatures);
873+
863874
#[cfg(test)]
864875
mod tests {
865-
use super::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, InvoiceFeatures, NodeFeatures};
876+
use super::{ChannelFeatures, ChannelTypeFeatures, InitFeatures, InvoiceFeatures, NodeFeatures, OfferFeatures};
866877
use bitcoin::bech32::{Base32Len, FromBase32, ToBase32, u5};
867878

868879
#[test]
@@ -873,6 +884,9 @@ mod tests {
873884
assert!(!InitFeatures::known().supports_unknown_bits());
874885
assert!(!NodeFeatures::known().requires_unknown_bits());
875886
assert!(!NodeFeatures::known().supports_unknown_bits());
887+
assert!(!InvoiceFeatures::known().supports_unknown_bits());
888+
assert!(!OfferFeatures::known().supports_unknown_bits());
889+
assert_eq!(OfferFeatures::known(), OfferFeatures::empty());
876890

877891
assert!(InitFeatures::known().supports_upfront_shutdown_script());
878892
assert!(NodeFeatures::known().supports_upfront_shutdown_script());

0 commit comments

Comments
 (0)