@@ -71,57 +71,28 @@ mod sealed {
71
71
use prelude:: * ;
72
72
use ln:: features:: Features ;
73
73
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.
76
77
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.
83
79
const KNOWN_FEATURE_MASK : & ' static [ u8 ] ;
84
80
}
85
81
86
82
/// Defines a [`Context`] by stating which features it requires and which are optional. Features
87
83
/// are specified as a comma-separated list of bytes where each byte is a pipe-delimited list of
88
84
/// feature identifiers.
89
85
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 ) |* , ) * ] ) => {
94
87
#[ derive( Eq , PartialEq ) ]
95
88
pub struct $context { }
96
89
97
90
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
-
115
91
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.
118
92
$(
119
93
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 ) * ,
125
96
) *
126
97
] ;
127
98
}
@@ -130,17 +101,12 @@ mod sealed {
130
101
fn fmt( & self , fmt: & mut alloc:: fmt:: Formatter ) -> Result <( ) , alloc:: fmt:: Error > {
131
102
$(
132
103
$(
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" }
142
107
else { "not supported" } ) ) ?;
143
108
) *
109
+ { } // Rust gets mad if we only have a $()* block here, so add a dummy {}
144
110
) *
145
111
fmt. write_fmt( format_args!( "unknown flags: {}" ,
146
112
if self . requires_unknown_bits( ) { "required" }
@@ -150,132 +116,65 @@ mod sealed {
150
116
} ;
151
117
}
152
118
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
+ ] ) ;
243
160
// This isn't a "real" feature context, and is only used in the channel_type field in an
244
161
// `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
+ ] ) ;
279
178
280
179
/// Defines a feature with the given bits for the specified [`Context`]s. The generated trait is
281
180
/// useful for manipulating feature flags.
0 commit comments