@@ -75,6 +75,30 @@ pub(crate) fn weight_received_htlc(channel_type_features: &ChannelTypeFeatures)
75
75
if channel_type_features. supports_anchors_zero_fee_htlc_tx ( ) { WEIGHT_RECEIVED_HTLC_ANCHORS } else { WEIGHT_RECEIVED_HTLC }
76
76
}
77
77
78
+ /// Verifies deserializable channel type features
79
+ pub ( crate ) fn verify_channel_type_features ( channel_type_features : & Option < ChannelTypeFeatures > , additional_permitted_features : Option < & ChannelTypeFeatures > ) -> Result < ( ) , DecodeError > {
80
+ if let Some ( features) = channel_type_features. as_ref ( ) {
81
+ if features. requires_unknown_bits ( ) {
82
+ return Err ( DecodeError :: UnknownRequiredFeature ) ;
83
+ }
84
+
85
+ let mut supported_feature_set = ChannelTypeFeatures :: anchors_zero_htlc_fee_and_dependencies ( ) ;
86
+ supported_feature_set. set_scid_privacy_required ( ) ;
87
+ supported_feature_set. set_zero_conf_required ( ) ;
88
+
89
+ // allow the passing of an additional necessary permitted flag
90
+ if let Some ( additional_permitted_features) = additional_permitted_features {
91
+ supported_feature_set |= additional_permitted_features;
92
+ }
93
+
94
+ if !features. is_subset ( & supported_feature_set) {
95
+ return Err ( DecodeError :: UnknownRequiredFeature ) ;
96
+ }
97
+ }
98
+
99
+ Ok ( ( ) )
100
+ }
101
+
78
102
// number_of_witness_elements + sig_length + revocation_sig + true_length + op_true + witness_script_length + witness_script
79
103
pub ( crate ) const WEIGHT_REVOKED_OUTPUT : u64 = 1 + 1 + 73 + 1 + 1 + 1 + 77 ;
80
104
@@ -239,6 +263,8 @@ impl Readable for CounterpartyOfferedHTLCOutput {
239
263
( 11 , channel_type_features, option) ,
240
264
} ) ;
241
265
266
+ verify_channel_type_features ( & channel_type_features, None ) ?;
267
+
242
268
Ok ( Self {
243
269
per_commitment_point : per_commitment_point. 0 . unwrap ( ) ,
244
270
counterparty_delayed_payment_base_key : counterparty_delayed_payment_base_key. 0 . unwrap ( ) ,
@@ -310,6 +336,8 @@ impl Readable for CounterpartyReceivedHTLCOutput {
310
336
( 9 , channel_type_features, option) ,
311
337
} ) ;
312
338
339
+ verify_channel_type_features ( & channel_type_features, None ) ?;
340
+
313
341
Ok ( Self {
314
342
per_commitment_point : per_commitment_point. 0 . unwrap ( ) ,
315
343
counterparty_delayed_payment_base_key : counterparty_delayed_payment_base_key. 0 . unwrap ( ) ,
@@ -385,6 +413,8 @@ impl Readable for HolderHTLCOutput {
385
413
( 7 , channel_type_features, option) ,
386
414
} ) ;
387
415
416
+ verify_channel_type_features ( & channel_type_features, None ) ?;
417
+
388
418
Ok ( Self {
389
419
amount_msat : amount_msat. 0 . unwrap ( ) ,
390
420
cltv_expiry : cltv_expiry. 0 . unwrap ( ) ,
@@ -444,6 +474,8 @@ impl Readable for HolderFundingOutput {
444
474
( 3 , funding_amount, option)
445
475
} ) ;
446
476
477
+ verify_channel_type_features ( & channel_type_features, None ) ?;
478
+
447
479
Ok ( Self {
448
480
funding_redeemscript : funding_redeemscript. 0 . unwrap ( ) ,
449
481
channel_type_features : channel_type_features. unwrap_or ( ChannelTypeFeatures :: only_static_remote_key ( ) ) ,
0 commit comments