@@ -32,6 +32,8 @@ use ln::msgs::DecodeError;
32
32
use util:: ser:: { Readable , Writeable , Writer } ;
33
33
34
34
mod sealed {
35
+ use ln:: features:: Features ;
36
+
35
37
/// The context in which [`Features`] are applicable. Defines which features are required and
36
38
/// which are optional for the context.
37
39
///
@@ -157,7 +159,8 @@ mod sealed {
157
159
///
158
160
/// [`Context`]: trait.Context.html
159
161
macro_rules! define_feature {
160
- ( $odd_bit: expr, $feature: ident, [ $( $context: ty) ,+] , $doc: expr) => {
162
+ ( $odd_bit: expr, $feature: ident, [ $( $context: ty) ,+] , $doc: expr, $optional_setter: ident,
163
+ $required_setter: ident) => {
161
164
#[ doc = $doc]
162
165
///
163
166
/// See [BOLT #9] for details.
@@ -242,6 +245,20 @@ mod sealed {
242
245
}
243
246
}
244
247
248
+ impl <T : $feature> Features <T > {
249
+ /// Set this feature as optional.
250
+ pub fn $optional_setter( mut self ) -> Self {
251
+ <T as $feature>:: set_optional_bit( & mut self . flags) ;
252
+ self
253
+ }
254
+
255
+ /// Set this feature as required.
256
+ pub fn $required_setter( mut self ) -> Self {
257
+ <T as $feature>:: set_required_bit( & mut self . flags) ;
258
+ self
259
+ }
260
+ }
261
+
245
262
$(
246
263
impl $feature for $context {
247
264
// EVEN_BIT % 2 == 0
@@ -251,28 +268,34 @@ mod sealed {
251
268
const ASSERT_ODD_BIT_PARITY : usize = ( <Self as $feature>:: ODD_BIT % 2 ) - 1 ;
252
269
}
253
270
) *
271
+
254
272
}
255
273
}
256
274
257
275
define_feature ! ( 1 , DataLossProtect , [ InitContext , NodeContext ] ,
258
- "Feature flags for `option_data_loss_protect`." ) ;
276
+ "Feature flags for `option_data_loss_protect`." , set_data_loss_protect_optional,
277
+ set_data_loss_protect_required) ;
259
278
// NOTE: Per Bolt #9, initial_routing_sync has no even bit.
260
- define_feature ! ( 3 , InitialRoutingSync , [ InitContext ] ,
261
- "Feature flags for `initial_routing_sync`." ) ;
279
+ define_feature ! ( 3 , InitialRoutingSync , [ InitContext ] , "Feature flags for `initial_routing_sync`." ,
280
+ set_initial_routing_sync_optional , set_initial_routing_sync_required ) ;
262
281
define_feature ! ( 5 , UpfrontShutdownScript , [ InitContext , NodeContext ] ,
263
- "Feature flags for `option_upfront_shutdown_script`." ) ;
282
+ "Feature flags for `option_upfront_shutdown_script`." , set_upfront_shutdown_script_optional,
283
+ set_upfront_shutdown_script_required) ;
264
284
define_feature ! ( 7 , GossipQueries , [ InitContext , NodeContext ] ,
265
- "Feature flags for `gossip_queries`." ) ;
285
+ "Feature flags for `gossip_queries`." , set_gossip_queries_optional , set_gossip_queries_required ) ;
266
286
define_feature ! ( 9 , VariableLengthOnion , [ InitContext , NodeContext , InvoiceContext ] ,
267
- "Feature flags for `var_onion_optin`." ) ;
287
+ "Feature flags for `var_onion_optin`." , set_variable_length_onion_optional,
288
+ set_variable_length_onion_required) ;
268
289
define_feature ! ( 13 , StaticRemoteKey , [ InitContext , NodeContext ] ,
269
- "Feature flags for `option_static_remotekey`." ) ;
290
+ "Feature flags for `option_static_remotekey`." , set_static_remote_key_optional,
291
+ set_static_remote_key_required) ;
270
292
define_feature ! ( 15 , PaymentSecret , [ InitContext , NodeContext , InvoiceContext ] ,
271
- "Feature flags for `payment_secret`." ) ;
293
+ "Feature flags for `payment_secret`." , set_payment_secret_optional , set_payment_secret_required ) ;
272
294
define_feature ! ( 17 , BasicMPP , [ InitContext , NodeContext , InvoiceContext ] ,
273
- "Feature flags for `basic_mpp`." ) ;
295
+ "Feature flags for `basic_mpp`." , set_basic_mpp_optional , set_basic_mpp_required ) ;
274
296
define_feature ! ( 27 , ShutdownAnySegwit , [ InitContext , NodeContext ] ,
275
- "Feature flags for `opt_shutdown_anysegwit`." ) ;
297
+ "Feature flags for `opt_shutdown_anysegwit`." , set_shutdown_any_segwit_optional,
298
+ set_shutdown_any_segwit_required) ;
276
299
277
300
#[ cfg( test) ]
278
301
define_context ! ( TestingContext {
@@ -296,7 +319,8 @@ mod sealed {
296
319
297
320
#[ cfg( test) ]
298
321
define_feature ! ( 23 , UnknownFeature , [ TestingContext ] ,
299
- "Feature flags for an unknown feature used in testing." ) ;
322
+ "Feature flags for an unknown feature used in testing." , set_unknown_feature_optional,
323
+ set_unknown_feature_required) ;
300
324
}
301
325
302
326
/// Tracks the set of features which a node implements, templated by the context in which it
@@ -614,7 +638,7 @@ impl<T: sealed::Context> Readable for Features<T> {
614
638
615
639
#[ cfg( test) ]
616
640
mod tests {
617
- use super :: { ChannelFeatures , InitFeatures , NodeFeatures } ;
641
+ use super :: { ChannelFeatures , InitFeatures , InvoiceFeatures , NodeFeatures } ;
618
642
619
643
#[ test]
620
644
fn sanity_test_known_features ( ) {
@@ -718,4 +742,15 @@ mod tests {
718
742
assert ! ( !features. supports_upfront_shutdown_script( ) ) ;
719
743
assert ! ( !init_features. supports_gossip_queries( ) ) ;
720
744
}
745
+
746
+ #[ test]
747
+ fn set_feature_bits ( ) {
748
+ let features = InvoiceFeatures :: empty ( )
749
+ . set_basic_mpp_optional ( )
750
+ . set_payment_secret_required ( ) ;
751
+ assert ! ( features. supports_basic_mpp( ) ) ;
752
+ assert ! ( !features. requires_basic_mpp( ) ) ;
753
+ assert ! ( features. requires_payment_secret( ) ) ;
754
+ assert ! ( features. supports_payment_secret( ) ) ;
755
+ }
721
756
}
0 commit comments