Skip to content

Commit 078379b

Browse files
committed
Define methods on ChannelTypeFeatures for anchors-related logic.
Specifically, introduce a new constructor for an anchors-supporting feature set, as well as methods that will maintain forwards-compatible deserialization in older versions.
1 parent 4e79eb5 commit 078379b

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

lightning/src/ln/features.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,66 @@ impl ChannelTypeFeatures {
581581
<sealed::ChannelTypeContext as sealed::StaticRemoteKey>::set_required_bit(&mut ret.flags);
582582
ret
583583
}
584+
585+
#[cfg(any(anchors, test))]
586+
/// Constructs a ChannelTypeFeatures with anchors support
587+
pub(crate) fn static_remote_key_with_anchors() -> Self {
588+
let mut ret = Self::empty();
589+
<sealed::ChannelTypeContext as sealed::StaticRemoteKey>::set_required_bit(&mut ret.flags);
590+
<sealed::ChannelTypeContext as sealed::AnchorsZeroFeeHtlcTx>::set_required_bit(&mut ret.flags);
591+
ret
592+
}
593+
594+
/// Simplified accessor for checking if anchors are supported
595+
pub fn supports_anchors(&self) -> bool {
596+
self.supports_anchors_zero_fee_htlc_tx()
597+
}
598+
599+
/// Simplified accessor for verifying support for anchors with nonzero fees
600+
pub fn supports_nonzero_fee_anchors(&self) -> bool {
601+
self.supports_anchors_nonzero_fee_htlc_tx()
602+
}
603+
604+
/// There are six legacy structs where we need [`ChannelTypeFeatures`] for keeping track of
605+
/// anchors and Taproot support. Those six structs are
606+
/// — [`ChannelTransactionParameters`]
607+
/// — [`CommitmentTransaction`]
608+
/// — [`CounterpartyOfferedHTLCOutput`]
609+
/// — [`CounterpartyReceivedHTLCOutput`]
610+
/// — [`HolderHTLCOutput`]
611+
/// — [`HolderFundingOutput`]
612+
/// Because pre-anchors versions of LDK do not expect additional fields on those structs,
613+
/// non-anchor channels must serialize non-anchor features as empty options, i. e. not
614+
/// serialize them at all.
615+
/// However, when instantiating those objects based on the full set of features determined
616+
/// in at channel construction, any additional feature bits will be lost in legacy channels.
617+
/// That would typically trigger an pre- and post-serialization equality check failure, so to
618+
/// avoid that, we hereby introduce a method that creates a watered-down, deserialization-safe
619+
/// copy.
620+
///
621+
/// [`ChannelTransactionParameters`]: crate::ln::chan_utils::ChannelTransactionParameters
622+
/// [`CommitmentTransaction`]: crate::ln::chan_utils::CommitmentTransaction
623+
/// [`CounterpartyOfferedHTLCOutput`]: crate::chain::package::CounterpartyOfferedHTLCOutput
624+
/// [`CounterpartyReceivedHTLCOutput`]: crate::chain::package::CounterpartyReceivedHTLCOutput
625+
/// [`HolderHTLCOutput`]: crate::chain::package::HolderHTLCOutput
626+
/// [`HolderFundingOutput`]: crate::chain::package::HolderFundingOutput
627+
pub(crate) fn legacy_serialization_safe_version(&self) -> Self {
628+
if self.supports_anchors() {
629+
self.clone()
630+
} else {
631+
Self::only_static_remote_key()
632+
}
633+
}
634+
635+
/// To actually serialize the features in a manner that won't break the structs read by
636+
/// older versions of LDK, we should skip serialization entirely if anchors are not supported.
637+
/// This is a helper method to do just that.
638+
pub(crate) fn serializable_option(&self) -> Option<Self> {
639+
if !self.supports_anchors() {
640+
return None;
641+
}
642+
Some(self.clone())
643+
}
584644
}
585645

586646
impl ToBase32 for InvoiceFeatures {

0 commit comments

Comments
 (0)