@@ -6,6 +6,9 @@ import fr.acinq.lightning.utils.leftPaddedCopyOf
66import fr.acinq.lightning.utils.or
77import kotlinx.serialization.Serializable
88
9+ /* * Feature scope as defined in Bolt 9. */
10+ enum class FeatureScope { Init , Node , Invoice }
11+
912enum class FeatureSupport {
1013 Mandatory {
1114 override fun toString () = " mandatory"
@@ -20,6 +23,7 @@ sealed class Feature {
2023
2124 abstract val rfcName: String
2225 abstract val mandatory: Int
26+ abstract val scopes: Set <FeatureScope >
2327 val optional: Int get() = mandatory + 1
2428
2529 fun supportBit (support : FeatureSupport ): Int = when (support) {
@@ -33,6 +37,7 @@ sealed class Feature {
3337 object OptionDataLossProtect : Feature() {
3438 override val rfcName get() = " option_data_loss_protect"
3539 override val mandatory get() = 0
40+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node )
3641 }
3742
3843 @Serializable
@@ -41,66 +46,84 @@ sealed class Feature {
4146
4247 // reserved but not used as per lightningnetwork/lightning-rfc/pull/178
4348 override val mandatory get() = 2
49+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init )
4450 }
4551
4652 @Serializable
4753 object ChannelRangeQueries : Feature() {
4854 override val rfcName get() = " gossip_queries"
4955 override val mandatory get() = 6
56+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node )
5057 }
5158
5259 @Serializable
5360 object VariableLengthOnion : Feature() {
5461 override val rfcName get() = " var_onion_optin"
5562 override val mandatory get() = 8
63+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node , FeatureScope .Invoice )
5664 }
5765
5866 @Serializable
5967 object ChannelRangeQueriesExtended : Feature() {
6068 override val rfcName get() = " gossip_queries_ex"
6169 override val mandatory get() = 10
70+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node )
6271 }
6372
6473 @Serializable
6574 object StaticRemoteKey : Feature() {
6675 override val rfcName get() = " option_static_remotekey"
6776 override val mandatory get() = 12
77+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node )
6878 }
6979
7080 @Serializable
7181 object PaymentSecret : Feature() {
7282 override val rfcName get() = " payment_secret"
7383 override val mandatory get() = 14
84+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node , FeatureScope .Invoice )
7485 }
7586
7687 @Serializable
7788 object BasicMultiPartPayment : Feature() {
7889 override val rfcName get() = " basic_mpp"
7990 override val mandatory get() = 16
91+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node , FeatureScope .Invoice )
8092 }
8193
8294 @Serializable
8395 object Wumbo : Feature() {
8496 override val rfcName get() = " option_support_large_channel"
8597 override val mandatory get() = 18
98+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node )
8699 }
87100
88101 @Serializable
89102 object AnchorOutputs : Feature() {
90103 override val rfcName get() = " option_anchor_outputs"
91104 override val mandatory get() = 20
105+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node )
92106 }
93107
94108 @Serializable
95109 object ShutdownAnySegwit : Feature() {
96110 override val rfcName get() = " option_shutdown_anysegwit"
97111 override val mandatory get() = 26
112+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node )
98113 }
99114
100115 @Serializable
101116 object ChannelType : Feature() {
102117 override val rfcName get() = " option_channel_type"
103118 override val mandatory get() = 44
119+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node )
120+ }
121+
122+ @Serializable
123+ object PaymentMetadata : Feature() {
124+ override val rfcName get() = " option_payment_metadata"
125+ override val mandatory get() = 48
126+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Invoice )
104127 }
105128
106129 // The following features have not been standardised, hence the high feature bits to avoid conflicts.
@@ -109,76 +132,87 @@ sealed class Feature {
109132 object TrampolinePayment : Feature() {
110133 override val rfcName get() = " trampoline_payment"
111134 override val mandatory get() = 50
135+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node , FeatureScope .Invoice )
112136 }
113137
114138 /* * This feature bit should be activated when a node accepts having their channel reserve set to 0. */
115139 @Serializable
116140 object ZeroReserveChannels : Feature() {
117141 override val rfcName get() = " zero_reserve_channels"
118142 override val mandatory get() = 128
143+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node )
119144 }
120145
121146 /* * This feature bit should be activated when a node accepts unconfirmed channels (will set min_depth to 0 in accept_channel). */
122147 @Serializable
123148 object ZeroConfChannels : Feature() {
124149 override val rfcName get() = " zero_conf_channels"
125150 override val mandatory get() = 130
151+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node )
126152 }
127153
128154 /* * This feature bit should be activated when a mobile node supports waking up via push notifications. */
129155 @Serializable
130156 object WakeUpNotificationClient : Feature() {
131157 override val rfcName get() = " wake_up_notification_client"
132158 override val mandatory get() = 132
159+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init )
133160 }
134161
135162 /* * This feature bit should be activated when a node supports waking up their peers via push notifications. */
136163 @Serializable
137164 object WakeUpNotificationProvider : Feature() {
138165 override val rfcName get() = " wake_up_notification_provider"
139166 override val mandatory get() = 134
167+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node )
140168 }
141169
142170 /* * This feature bit should be activated when a node accepts on-the-fly channel creation. */
143171 @Serializable
144172 object PayToOpenClient : Feature() {
145173 override val rfcName get() = " pay_to_open_client"
146174 override val mandatory get() = 136
175+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init )
147176 }
148177
149178 /* * This feature bit should be activated when a node supports opening channels on-the-fly when liquidity is missing to receive a payment. */
150179 @Serializable
151180 object PayToOpenProvider : Feature() {
152181 override val rfcName get() = " pay_to_open_provider"
153182 override val mandatory get() = 138
183+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node )
154184 }
155185
156186 /* * This feature bit should be activated when a node accepts channel creation via trusted swaps-in. */
157187 @Serializable
158188 object TrustedSwapInClient : Feature() {
159189 override val rfcName get() = " trusted_swap_in_client"
160190 override val mandatory get() = 140
191+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init )
161192 }
162193
163194 /* * This feature bit should be activated when a node supports opening channels in exchange for on-chain funds (swap-in). */
164195 @Serializable
165196 object TrustedSwapInProvider : Feature() {
166197 override val rfcName get() = " trusted_swap_in_provider"
167198 override val mandatory get() = 142
199+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node )
168200 }
169201
170202 /* * This feature bit should be activated when a node wants to send channel backups to their peers. */
171203 @Serializable
172204 object ChannelBackupClient : Feature() {
173205 override val rfcName get() = " channel_backup_client"
174206 override val mandatory get() = 144
207+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init )
175208 }
176209
177210 /* * This feature bit should be activated when a node stores channel backups for their peers. */
178211 @Serializable
179212 object ChannelBackupProvider : Feature() {
180213 override val rfcName get() = " channel_backup_provider"
181214 override val mandatory get() = 146
215+ override val scopes: Set <FeatureScope > get() = setOf (FeatureScope .Init , FeatureScope .Node )
182216 }
183217}
184218
@@ -188,9 +222,16 @@ data class UnknownFeature(val bitIndex: Int)
188222@Serializable
189223data class Features (val activated : Map <Feature , FeatureSupport >, val unknown : Set <UnknownFeature > = emptySet()) {
190224
191- fun hasFeature (feature : Feature , support : FeatureSupport ? = null): Boolean =
192- if (support != null ) activated[feature] == support
193- else activated.containsKey(feature)
225+ fun hasFeature (feature : Feature , support : FeatureSupport ? = null): Boolean = when (support) {
226+ null -> activated.containsKey(feature)
227+ else -> activated[feature] == support
228+ }
229+
230+ fun initFeatures (): Features = Features (activated.filter { it.key.scopes.contains(FeatureScope .Init ) }, unknown)
231+
232+ fun nodeAnnouncementFeatures (): Features = Features (activated.filter { it.key.scopes.contains(FeatureScope .Node ) }, unknown)
233+
234+ fun invoiceFeatures (): Features = Features (activated.filter { it.key.scopes.contains(FeatureScope .Invoice ) }, unknown)
194235
195236 /* * NB: this method is not reflexive, see [[Features.areCompatible]] if you want symmetric validation. */
196237 fun areSupported (remoteFeatures : Features ): Boolean {
@@ -236,6 +277,7 @@ data class Features(val activated: Map<Feature, FeatureSupport>, val unknown: Se
236277 Feature .AnchorOutputs ,
237278 Feature .ShutdownAnySegwit ,
238279 Feature .ChannelType ,
280+ Feature .PaymentMetadata ,
239281 Feature .TrampolinePayment ,
240282 Feature .ZeroReserveChannels ,
241283 Feature .ZeroConfChannels ,
0 commit comments