You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We were not handling correctly feature-less invoices, which are
spec-compliant. We do reject invoices that don't have
`var_onion_optin`, but the check happens later. Instead, we currently
throw a `NullPointerException`.
The way we are checking requirements in the `init` block requires
lazy-init properties, otherwise the object initialization will fail
before any logic can happen.
Also, as per the spec, the feature tag must be skipped at serialization if
there are no features enabled.
val paymentSecret:ByteVector32= tags.find { it isTaggedField.PaymentSecret }!!.run { (thisasTaggedField.PaymentSecret).secret }
28
+
val paymentSecret:ByteVector32get() = tags.find { it isTaggedField.PaymentSecret }!!.run { (thisasTaggedField.PaymentSecret).secret }
29
29
30
-
val paymentMetadata:ByteVector?= tags.find { it isTaggedField.PaymentMetadata }?.run { (thisasTaggedField.PaymentMetadata).data }
30
+
val paymentMetadata:ByteVector?get() = tags.find { it isTaggedField.PaymentMetadata }?.run { (thisasTaggedField.PaymentMetadata).data }
31
31
32
-
val description:String?= tags.find { it isTaggedField.Description }?.run { (thisasTaggedField.Description).description }
32
+
val description:String?get() = tags.find { it isTaggedField.Description }?.run { (thisasTaggedField.Description).description }
33
33
34
-
val descriptionHash:ByteVector32?= tags.find { it isTaggedField.DescriptionHash }?.run { (thisasTaggedField.DescriptionHash).hash }
34
+
val descriptionHash:ByteVector32?get() = tags.find { it isTaggedField.DescriptionHash }?.run { (thisasTaggedField.DescriptionHash).hash }
35
35
36
-
val expirySeconds:Long?= tags.find { it isTaggedField.Expiry }?.run { (thisasTaggedField.Expiry).expirySeconds }
36
+
val expirySeconds:Long?get() = tags.find { it isTaggedField.Expiry }?.run { (thisasTaggedField.Expiry).expirySeconds }
37
37
38
-
val minFinalExpiryDelta:CltvExpiryDelta?= tags.find { it isTaggedField.MinFinalCltvExpiry }?.run { CltvExpiryDelta((thisasTaggedField.MinFinalCltvExpiry).cltvExpiry.toInt()) }
38
+
val minFinalExpiryDelta:CltvExpiryDelta?get() = tags.find { it isTaggedField.MinFinalCltvExpiry }?.run { CltvExpiryDelta((thisasTaggedField.MinFinalCltvExpiry).cltvExpiry.toInt()) }
39
39
40
40
val fallbackAddress:String?= tags.find { it isTaggedField.FallbackAddress }?.run { (thisasTaggedField.FallbackAddress).toAddress(prefix) }
41
41
42
-
overrideval features:Features= tags.find { it isTaggedField.Features }.run { Features((thisasTaggedField.Features).bits) }
.let { failure -> assertContains(failure.error.message ?:"", "there must be exactly one payment secret tag") }
505
508
506
509
// Invoices must use a payment secret.
507
510
assertFails {
@@ -517,6 +520,13 @@ class Bolt11InvoiceTestsCommon : LightningTestSuite() {
517
520
}
518
521
}
519
522
523
+
@Test
524
+
fun`decode invoice without features`() {
525
+
val s ="lnbc10n1pnglwsfpp5fdcjk5vudhe2jzuz0q65dkh4gfmxnn6vexlchc6ta9f25wynp2qshp59warmg27z4nkuvhs5x3vdv998jck5ue8nge2t68dtfvm27n8kvsqxqrrssnp4qf3rsvu5xdrxnv2kgkr4hvpefx257fjw8ugupnug4ls6rf2d5w6yc2rnnz0zuymgjl3p4dvyh8dr4mp969gjrnaggx50nv5ax7wy6yflyr07ek5hdevxtz9angp3jfyfz9ram8d7gw9pr0csr6fpa8rfeu7gpgesr58"
526
+
val failure = assertIs<Try.Failure<Throwable>>(Bolt11Invoice.read(s))
527
+
assertContains(failure.error.message ?:"", "var_onion_optin must be supported")
0 commit comments