@@ -71,57 +71,28 @@ mod sealed {
7171 use prelude:: * ;
7272 use ln:: features:: Features ;
7373
74- /// The context in which [`Features`] are applicable. Defines which features are required and
75- /// which are optional for the context.
74+ /// The context in which [`Features`] are applicable. Defines which features are known to the
75+ /// implementation, though specification of them as required or optional is up to the code
76+ /// constructing a features object.
7677 pub trait Context {
77- /// Features that are known to the implementation, where a required feature is indicated by
78- /// its even bit and an optional feature is indicated by its odd bit.
79- const KNOWN_FEATURE_FLAGS : & ' static [ u8 ] ;
80-
81- /// Bitmask for selecting features that are known to the implementation, regardless of
82- /// whether each feature is required or optional.
78+ /// Bitmask for selecting features that are known to the implementation.
8379 const KNOWN_FEATURE_MASK : & ' static [ u8 ] ;
8480 }
8581
8682 /// Defines a [`Context`] by stating which features it requires and which are optional. Features
8783 /// are specified as a comma-separated list of bytes where each byte is a pipe-delimited list of
8884 /// feature identifiers.
8985 macro_rules! define_context {
90- ( $context: ident {
91- required_features: [ $( $( $required_feature: ident ) |* , ) * ] ,
92- optional_features: [ $( $( $optional_feature: ident ) |* , ) * ] ,
93- } ) => {
86+ ( $context: ident, [ $( $( $known_feature: ident ) |* , ) * ] ) => {
9487 #[ derive( Eq , PartialEq ) ]
9588 pub struct $context { }
9689
9790 impl Context for $context {
98- const KNOWN_FEATURE_FLAGS : & ' static [ u8 ] = & [
99- // For each byte, use bitwise-OR to compute the applicable flags for known
100- // required features `r_i` and optional features `o_j` for all `i` and `j` such
101- // that the following slice is formed:
102- //
103- // [
104- // `r_0` | `r_1` | ... | `o_0` | `o_1` | ...,
105- // ...,
106- // ]
107- $(
108- 0b00_00_00_00 $( |
109- <Self as $required_feature>:: REQUIRED_MASK ) *
110- $( |
111- <Self as $optional_feature>:: OPTIONAL_MASK ) * ,
112- ) *
113- ] ;
114-
11591 const KNOWN_FEATURE_MASK : & ' static [ u8 ] = & [
116- // Similar as above, but set both flags for each feature regardless of whether
117- // the feature is required or optional.
11892 $(
11993 0b00_00_00_00 $( |
120- <Self as $required_feature>:: REQUIRED_MASK |
121- <Self as $required_feature>:: OPTIONAL_MASK ) *
122- $( |
123- <Self as $optional_feature>:: REQUIRED_MASK |
124- <Self as $optional_feature>:: OPTIONAL_MASK ) * ,
94+ <Self as $known_feature>:: REQUIRED_MASK |
95+ <Self as $known_feature>:: OPTIONAL_MASK ) * ,
12596 ) *
12697 ] ;
12798 }
@@ -130,17 +101,12 @@ mod sealed {
130101 fn fmt( & self , fmt: & mut alloc:: fmt:: Formatter ) -> Result <( ) , alloc:: fmt:: Error > {
131102 $(
132103 $(
133- fmt. write_fmt( format_args!( "{}: {}, " , stringify!( $required_feature) ,
134- if <$context as $required_feature>:: requires_feature( & self . flags) { "required" }
135- else if <$context as $required_feature>:: supports_feature( & self . flags) { "supported" }
136- else { "not supported" } ) ) ?;
137- ) *
138- $(
139- fmt. write_fmt( format_args!( "{}: {}, " , stringify!( $optional_feature) ,
140- if <$context as $optional_feature>:: requires_feature( & self . flags) { "required" }
141- else if <$context as $optional_feature>:: supports_feature( & self . flags) { "supported" }
104+ fmt. write_fmt( format_args!( "{}: {}, " , stringify!( $known_feature) ,
105+ if <$context as $known_feature>:: requires_feature( & self . flags) { "required" }
106+ else if <$context as $known_feature>:: supports_feature( & self . flags) { "supported" }
142107 else { "not supported" } ) ) ?;
143108 ) *
109+ { } // Rust gets mad if we only have a $()* block here, so add a dummy {}
144110 ) *
145111 fmt. write_fmt( format_args!( "unknown flags: {}" ,
146112 if self . requires_unknown_bits( ) { "required" }
@@ -150,132 +116,65 @@ mod sealed {
150116 } ;
151117 }
152118
153- define_context ! ( InitContext {
154- required_features: [
155- // Byte 0
156- ,
157- // Byte 1
158- VariableLengthOnion | StaticRemoteKey | PaymentSecret ,
159- // Byte 2
160- ,
161- // Byte 3
162- ,
163- // Byte 4
164- ,
165- // Byte 5
166- ,
167- // Byte 6
168- ,
169- ] ,
170- optional_features: [
171- // Byte 0
172- DataLossProtect | InitialRoutingSync | UpfrontShutdownScript | GossipQueries ,
173- // Byte 1
174- ,
175- // Byte 2
176- BasicMPP | Wumbo ,
177- // Byte 3
178- ShutdownAnySegwit ,
179- // Byte 4
180- OnionMessages ,
181- // Byte 5
182- ChannelType | SCIDPrivacy ,
183- // Byte 6
184- ZeroConf ,
185- ] ,
186- } ) ;
187- define_context ! ( NodeContext {
188- required_features: [
189- // Byte 0
190- ,
191- // Byte 1
192- VariableLengthOnion | StaticRemoteKey | PaymentSecret ,
193- // Byte 2
194- ,
195- // Byte 3
196- ,
197- // Byte 4
198- ,
199- // Byte 5
200- ,
201- // Byte 6
202- ,
203- ] ,
204- optional_features: [
205- // Byte 0
206- DataLossProtect | UpfrontShutdownScript | GossipQueries ,
207- // Byte 1
208- ,
209- // Byte 2
210- BasicMPP | Wumbo ,
211- // Byte 3
212- ShutdownAnySegwit ,
213- // Byte 4
214- OnionMessages ,
215- // Byte 5
216- ChannelType | SCIDPrivacy ,
217- // Byte 6
218- ZeroConf | Keysend ,
219- ] ,
220- } ) ;
221- define_context ! ( ChannelContext {
222- required_features: [ ] ,
223- optional_features: [ ] ,
224- } ) ;
225- define_context ! ( InvoiceContext {
226- required_features: [
227- // Byte 0
228- ,
229- // Byte 1
230- VariableLengthOnion | PaymentSecret ,
231- // Byte 2
232- ,
233- ] ,
234- optional_features: [
235- // Byte 0
236- ,
237- // Byte 1
238- ,
239- // Byte 2
240- BasicMPP ,
241- ] ,
242- } ) ;
119+ define_context ! ( InitContext , [
120+ // Byte 0
121+ DataLossProtect | InitialRoutingSync | UpfrontShutdownScript | GossipQueries ,
122+ // Byte 1
123+ VariableLengthOnion | StaticRemoteKey | PaymentSecret ,
124+ // Byte 2
125+ BasicMPP | Wumbo ,
126+ // Byte 3
127+ ShutdownAnySegwit ,
128+ // Byte 4
129+ OnionMessages ,
130+ // Byte 5
131+ ChannelType | SCIDPrivacy ,
132+ // Byte 6
133+ ZeroConf ,
134+ ] ) ;
135+ define_context ! ( NodeContext , [
136+ // Byte 0
137+ DataLossProtect | UpfrontShutdownScript | GossipQueries ,
138+ // Byte 1
139+ VariableLengthOnion | StaticRemoteKey | PaymentSecret ,
140+ // Byte 2
141+ BasicMPP | Wumbo ,
142+ // Byte 3
143+ ShutdownAnySegwit ,
144+ // Byte 4
145+ OnionMessages ,
146+ // Byte 5
147+ ChannelType | SCIDPrivacy ,
148+ // Byte 6
149+ ZeroConf | Keysend ,
150+ ] ) ;
151+ define_context ! ( ChannelContext , [ ] ) ;
152+ define_context ! ( InvoiceContext , [
153+ // Byte 0
154+ ,
155+ // Byte 1
156+ VariableLengthOnion | PaymentSecret ,
157+ // Byte 2
158+ BasicMPP ,
159+ ] ) ;
243160 // This isn't a "real" feature context, and is only used in the channel_type field in an
244161 // `OpenChannel` message.
245- define_context ! ( ChannelTypeContext {
246- required_features: [
247- // Byte 0
248- ,
249- // Byte 1
250- StaticRemoteKey ,
251- // Byte 2
252- ,
253- // Byte 3
254- ,
255- // Byte 4
256- ,
257- // Byte 5
258- SCIDPrivacy ,
259- // Byte 6
260- ZeroConf ,
261- ] ,
262- optional_features: [
263- // Byte 0
264- ,
265- // Byte 1
266- ,
267- // Byte 2
268- ,
269- // Byte 3
270- ,
271- // Byte 4
272- ,
273- // Byte 5
274- ,
275- // Byte 6
276- ,
277- ] ,
278- } ) ;
162+ define_context ! ( ChannelTypeContext , [
163+ // Byte 0
164+ ,
165+ // Byte 1
166+ StaticRemoteKey ,
167+ // Byte 2
168+ ,
169+ // Byte 3
170+ ,
171+ // Byte 4
172+ ,
173+ // Byte 5
174+ SCIDPrivacy ,
175+ // Byte 6
176+ ZeroConf ,
177+ ] ) ;
279178
280179 /// Defines a feature with the given bits for the specified [`Context`]s. The generated trait is
281180 /// useful for manipulating feature flags.
0 commit comments