+ /// Defines a [`Context`] by stating which features it requires and which are optional. Features
+ /// are specified as a comma-separated list of bytes where each byte is a pipe-delimited list of
+ /// feature identifiers.
+ ///
+ /// [`Context`]: trait.Context.html
+ macro_rules! define_context {
+ ($context: ident {
+ required_features: [$( $( $required_feature: ident )|*, )*],
+ optional_features: [$( $( $optional_feature: ident )|*, )*],
+ }) => {
+ pub struct $context {}
+
+ impl Context for $context {
+ const KNOWN_FEATURE_FLAGS: &'static [u8] = &[
+ // For each byte, use bitwise-OR to compute the applicable flags for known
+ // required features `r_i` and optional features `o_j` for all `i` and `j` such
+ // that the following slice is formed:
+ //
+ // [
+ // `r_0` | `r_1` | ... | `o_0` | `o_1` | ...,
+ // ...,
+ // ]
+ $(
+ 0b00_00_00_00 $(|
+ <Self as $required_feature>::REQUIRED_MASK)*
+ $(|
+ <Self as $optional_feature>::OPTIONAL_MASK)*,
+ )*
+ ];
+
+ const KNOWN_FEATURE_MASK: &'static [u8] = &[
+ // Similar as above, but set both flags for each feature regardless of whether
+ // the feature is required or optional.
+ $(
+ 0b00_00_00_00 $(|
+ <Self as $required_feature>::REQUIRED_MASK |
+ <Self as $required_feature>::OPTIONAL_MASK)*
+ $(|
+ <Self as $optional_feature>::REQUIRED_MASK |
+ <Self as $optional_feature>::OPTIONAL_MASK)*,
+ )*
+ ];
+ }
+ };
+ }
+
+ define_context!(InitContext {
+ required_features: [
+ // Byte 0
+ ,
+ // Byte 1
+ StaticRemoteKey,
+ // Byte 2
+ ,
+ ],
+ optional_features: [
+ // Byte 0
+ DataLossProtect | InitialRoutingSync | UpfrontShutdownScript,
+ // Byte 1
+ VariableLengthOnion | PaymentSecret,
+ // Byte 2
+ BasicMPP,
+ ],
+ });
+ define_context!(NodeContext {
+ required_features: [
+ // Byte 0
+ ,
+ // Byte 1
+ StaticRemoteKey,
+ // Byte 2
+ ,
+ ],
+ optional_features: [
+ // Byte 0
+ DataLossProtect | UpfrontShutdownScript,
+ // Byte 1
+ VariableLengthOnion | PaymentSecret,
+ // Byte 2
+ BasicMPP,
+ ],
+ });
+ define_context!(ChannelContext {
+ required_features: [],
+ optional_features: [],
+ });