Verify channel type features for decoding.
authorArik Sosman <git@arik.io>
Tue, 20 Jun 2023 20:17:28 +0000 (13:17 -0700)
committerArik Sosman <git@arik.io>
Fri, 23 Jun 2023 17:37:14 +0000 (10:37 -0700)
lightning/src/chain/package.rs
lightning/src/ln/chan_utils.rs
lightning/src/ln/features.rs

index 0b7dbd462f47044561f5468693cfa9a27b68e8a1..891d7d1da33bddbeb8777c1349e1eda0a4c5a668 100644 (file)
@@ -75,6 +75,30 @@ pub(crate) fn weight_received_htlc(channel_type_features: &ChannelTypeFeatures)
        if channel_type_features.supports_anchors_zero_fee_htlc_tx() { WEIGHT_RECEIVED_HTLC_ANCHORS } else { WEIGHT_RECEIVED_HTLC }
 }
 
+/// Verifies deserializable channel type features
+pub(crate) fn verify_channel_type_features(channel_type_features: &Option<ChannelTypeFeatures>, additional_permitted_features: Option<&ChannelTypeFeatures>) -> Result<(), DecodeError> {
+       if let Some(features) = channel_type_features.as_ref() {
+               if features.requires_unknown_bits() {
+                       return Err(DecodeError::UnknownRequiredFeature);
+               }
+
+               let mut supported_feature_set = ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies();
+               supported_feature_set.set_scid_privacy_required();
+               supported_feature_set.set_zero_conf_required();
+
+               // allow the passing of an additional necessary permitted flag
+               if let Some(additional_permitted_features) = additional_permitted_features {
+                       supported_feature_set |= additional_permitted_features;
+               }
+
+               if !features.is_subset(&supported_feature_set) {
+                       return Err(DecodeError::UnknownRequiredFeature);
+               }
+       }
+
+       Ok(())
+}
+
 // number_of_witness_elements + sig_length + revocation_sig + true_length + op_true + witness_script_length + witness_script
 pub(crate) const WEIGHT_REVOKED_OUTPUT: u64 = 1 + 1 + 73 + 1 + 1 + 1 + 77;
 
@@ -239,6 +263,8 @@ impl Readable for CounterpartyOfferedHTLCOutput {
                        (11, channel_type_features, option),
                });
 
+               verify_channel_type_features(&channel_type_features, None)?;
+
                Ok(Self {
                        per_commitment_point: per_commitment_point.0.unwrap(),
                        counterparty_delayed_payment_base_key: counterparty_delayed_payment_base_key.0.unwrap(),
@@ -310,6 +336,8 @@ impl Readable for CounterpartyReceivedHTLCOutput {
                        (9, channel_type_features, option),
                });
 
+               verify_channel_type_features(&channel_type_features, None)?;
+
                Ok(Self {
                        per_commitment_point: per_commitment_point.0.unwrap(),
                        counterparty_delayed_payment_base_key: counterparty_delayed_payment_base_key.0.unwrap(),
@@ -385,6 +413,8 @@ impl Readable for HolderHTLCOutput {
                        (7, channel_type_features, option),
                });
 
+               verify_channel_type_features(&channel_type_features, None)?;
+
                Ok(Self {
                        amount_msat: amount_msat.0.unwrap(),
                        cltv_expiry: cltv_expiry.0.unwrap(),
@@ -444,6 +474,8 @@ impl Readable for HolderFundingOutput {
                        (3, funding_amount, option)
                });
 
+               verify_channel_type_features(&channel_type_features, None)?;
+
                Ok(Self {
                        funding_redeemscript: funding_redeemscript.0.unwrap(),
                        channel_type_features: channel_type_features.unwrap_or(ChannelTypeFeatures::only_static_remote_key()),
index d570347fef879af540cdfea9f5a68e9b22f3f57f..7fa2308d001cc59b97235bb466d97f7592e462d2 100644 (file)
@@ -952,6 +952,10 @@ impl Readable for ChannelTransactionParameters {
                        (11, channel_type_features, option),
                });
 
+               let mut additional_features = ChannelTypeFeatures::empty();
+               additional_features.set_anchors_nonzero_fee_htlc_tx_required();
+               chain::package::verify_channel_type_features(&channel_type_features, Some(&additional_features))?;
+
                Ok(Self {
                        holder_pubkeys: holder_pubkeys.0.unwrap(),
                        holder_selected_contest_delay: holder_selected_contest_delay.0.unwrap(),
@@ -1375,6 +1379,10 @@ impl Readable for CommitmentTransaction {
                        (15, channel_type_features, option),
                });
 
+               let mut additional_features = ChannelTypeFeatures::empty();
+               additional_features.set_anchors_nonzero_fee_htlc_tx_required();
+               chain::package::verify_channel_type_features(&channel_type_features, Some(&additional_features))?;
+
                Ok(Self {
                        commitment_number: commitment_number.0.unwrap(),
                        to_broadcaster_value_sat: to_broadcaster_value_sat.0.unwrap(),
index 714bfaa5528fab5a5144cd9e54b827bb7de3b422..ca6ea70b61da7312de22b1e28749a51cb3f28941 100644 (file)
@@ -595,7 +595,6 @@ impl ChannelTypeFeatures {
                ret
        }
 
-       #[cfg(any(anchors, test))]
        /// Constructs a ChannelTypeFeatures with anchors support
        pub(crate) fn anchors_zero_htlc_fee_and_dependencies() -> Self {
                let mut ret = Self::empty();