Skip to content

Commit 7d9f7ad

Browse files
committed
Add a ChannelTypeFeatures features object for the new channel_type
Its semantics are somewhat different from existing features, however not enough to merit a different struct entirely. Specifically, it only supports required features (if you send a channel_type, the counterparty has to accept it wholesale or try again, it cannot select only a subset of the flags) and it is serialized differently (only appearing in TLVs).
1 parent 0878d74 commit 7d9f7ad

File tree

1 file changed

+91
-16
lines changed

1 file changed

+91
-16
lines changed

lightning/src/ln/features.rs

Lines changed: 91 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
//! [BOLT #9]: https://github.com/lightningnetwork/lightning-rfc/blob/master/09-features.md
2323
//! [messages]: crate::ln::msgs
2424
25-
use io;
25+
use {io, io_extras};
2626
use prelude::*;
2727
use core::{cmp, fmt};
2828
use core::hash::{Hash, Hasher};
@@ -194,6 +194,30 @@ mod sealed {
194194
BasicMPP,
195195
],
196196
});
197+
// This isn't a "real" feature context, and is only used in the channel_type field in an
198+
// `OpenChannel` message.
199+
define_context!(ChannelTypeContext {
200+
required_features: [
201+
// Byte 0
202+
,
203+
// Byte 1
204+
StaticRemoteKey,
205+
// Byte 2
206+
,
207+
// Byte 3
208+
,
209+
],
210+
optional_features: [
211+
// Byte 0
212+
,
213+
// Byte 1
214+
,
215+
// Byte 2
216+
,
217+
// Byte 3
218+
,
219+
],
220+
});
197221

198222
/// Defines a feature with the given bits for the specified [`Context`]s. The generated trait is
199223
/// useful for manipulating feature flags.
@@ -325,7 +349,7 @@ mod sealed {
325349
define_feature!(9, VariableLengthOnion, [InitContext, NodeContext, InvoiceContext],
326350
"Feature flags for `var_onion_optin`.", set_variable_length_onion_optional,
327351
set_variable_length_onion_required);
328-
define_feature!(13, StaticRemoteKey, [InitContext, NodeContext],
352+
define_feature!(13, StaticRemoteKey, [InitContext, NodeContext, ChannelTypeContext],
329353
"Feature flags for `option_static_remotekey`.", set_static_remote_key_optional,
330354
set_static_remote_key_required);
331355
define_feature!(15, PaymentSecret, [InitContext, NodeContext, InvoiceContext],
@@ -388,6 +412,18 @@ pub type ChannelFeatures = Features<sealed::ChannelContext>;
388412
/// Features used within an invoice.
389413
pub type InvoiceFeatures = Features<sealed::InvoiceContext>;
390414

415+
/// Features used within the channel_type field in an OpenChannel message.
416+
///
417+
/// A channel is always of some known "type", describing the transaction formats used and the exact
418+
/// semantics of our interaction with our peer.
419+
///
420+
/// Note that because a channel is a specific type which is proposed by the opener and accepted by
421+
/// the counterparty, only required features are allowed here.
422+
///
423+
/// This is serialized differently from other feature types - it is not prefixed by a length, and
424+
/// thus must only appear inside a TLV where its length is known in advance.
425+
pub type ChannelTypeFeatures = Features<sealed::ChannelTypeContext>;
426+
391427
impl InitFeatures {
392428
/// Writes all features present up to, and including, 13.
393429
pub(crate) fn write_up_to_13<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
@@ -442,6 +478,21 @@ impl InvoiceFeatures {
442478
}
443479
}
444480

481+
impl ChannelTypeFeatures {
482+
/// Constructs the implicit channel type based on the common supported types between us and our
483+
/// counterparty
484+
pub(crate) fn from_counterparty_init(counterparty_init: &InitFeatures) -> Self {
485+
counterparty_init.to_context_internal()
486+
}
487+
488+
/// Constructs a ChannelTypeFeatures with only static_remotekey set
489+
pub(crate) fn only_static_remote_key() -> Self {
490+
let mut ret = Self::empty();
491+
<sealed::ChannelTypeContext as sealed::StaticRemoteKey>::set_required_bit(&mut ret.flags);
492+
ret
493+
}
494+
}
495+
445496
impl ToBase32 for InvoiceFeatures {
446497
fn write_base32<W: WriteBase32>(&self, writer: &mut W) -> Result<(), <W as WriteBase32>::Err> {
447498
// Explanation for the "4": the normal way to round up when dividing is to add the divisor
@@ -553,6 +604,20 @@ impl<T: sealed::Context> Features<T> {
553604
&self.flags
554605
}
555606

607+
fn write_be<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
608+
for f in self.flags.iter().rev() { // Swap back to big-endian
609+
f.write(w)?;
610+
}
611+
Ok(())
612+
}
613+
fn from_be_bytes(mut flags: Vec<u8>) -> Features<T> {
614+
flags.reverse(); // Swap to little-endian
615+
Self {
616+
flags,
617+
mark: PhantomData,
618+
}
619+
}
620+
556621
/// Returns true if this `Features` object contains unknown feature flags which are set as
557622
/// "required".
558623
pub fn requires_unknown_bits(&self) -> bool {
@@ -692,25 +757,35 @@ impl<T: sealed::ShutdownAnySegwit> Features<T> {
692757
self
693758
}
694759
}
695-
696-
impl<T: sealed::Context> Writeable for Features<T> {
697-
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
698-
(self.flags.len() as u16).write(w)?;
699-
for f in self.flags.iter().rev() { // Swap back to big-endian
700-
f.write(w)?;
760+
macro_rules! impl_feature_len_prefixed_write {
761+
($features: ident) => {
762+
impl Writeable for $features {
763+
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
764+
(self.flags.len() as u16).write(w)?;
765+
self.write_be(w)
766+
}
767+
}
768+
impl Readable for $features {
769+
fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
770+
Ok(Self::from_be_bytes(Vec::<u8>::read(r)?))
771+
}
701772
}
702-
Ok(())
703773
}
704774
}
775+
impl_feature_len_prefixed_write!(InitFeatures);
776+
impl_feature_len_prefixed_write!(ChannelFeatures);
777+
impl_feature_len_prefixed_write!(NodeFeatures);
778+
impl_feature_len_prefixed_write!(InvoiceFeatures);
705779

706-
impl<T: sealed::Context> Readable for Features<T> {
780+
impl Writeable for ChannelTypeFeatures {
781+
fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
782+
self.write_be(w)
783+
}
784+
}
785+
impl Readable for ChannelTypeFeatures {
707786
fn read<R: io::Read>(r: &mut R) -> Result<Self, DecodeError> {
708-
let mut flags: Vec<u8> = Readable::read(r)?;
709-
flags.reverse(); // Swap to little-endian
710-
Ok(Self {
711-
flags,
712-
mark: PhantomData,
713-
})
787+
let v = io_extras::read_to_end(r)?;
788+
Ok(Self::from_be_bytes(v))
714789
}
715790
}
716791

0 commit comments

Comments
 (0)