Skip to content

Commit

Permalink
Use try pattern for PaymentRequest.read (#492)
Browse files Browse the repository at this point in the history
See ACINQ/lightning-kmp#567 which catches invoice decoding
exceptions.
  • Loading branch information
dpad85 authored Jan 22, 2024
1 parent ca24d8c commit 1309372
Show file tree
Hide file tree
Showing 10 changed files with 21 additions and 22 deletions.
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
object Versions {
const val lightningKmp = "1.5.14"
const val lightningKmp = "1.5.15-SNAPSHOT"
const val secp256k1 = "0.11.0"
const val torMobile = "0.2.0"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ object LegacyMigrationHelper {
}
} else {
IncomingPayment.Origin.Invoice(
paymentRequest = PaymentRequest.read(fr.acinq.eclair.payment.PaymentRequest.write(payment.paymentRequest()))
paymentRequest = PaymentRequest.read(fr.acinq.eclair.payment.PaymentRequest.write(payment.paymentRequest())).get()
)
}

Expand Down Expand Up @@ -363,7 +363,7 @@ object LegacyMigrationHelper {
}

val paymentRequest = if (head.paymentRequest().isDefined) {
PaymentRequest.read(fr.acinq.eclair.payment.PaymentRequest.write(head.paymentRequest().get()))
PaymentRequest.read(fr.acinq.eclair.payment.PaymentRequest.write(head.paymentRequest().get())).get()
} else null

// retrieve details from the first payment in the list
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import fr.acinq.bitcoin.ByteVector
import fr.acinq.bitcoin.Crypto
import fr.acinq.lightning.MilliSatoshi
import fr.acinq.lightning.payment.PaymentRequest
import fr.acinq.lightning.utils.Try
import fr.acinq.phoenix.data.lnurl.Lnurl.Companion.format
import fr.acinq.phoenix.data.lnurl.Lnurl.Companion.log
import fr.acinq.phoenix.db.cloud.b64Decode
Expand Down Expand Up @@ -111,10 +112,9 @@ sealed class LnurlPay : Lnurl.Qualified {
): Invoice {
try {
val pr = json["pr"]?.jsonPrimitive?.content ?: throw LnurlError.Pay.Invoice.Malformed(origin, "missing pr")
val paymentRequest = try {
PaymentRequest.read(pr) // <- throws
} catch (t: Throwable) {
throw LnurlError.Pay.Invoice.Malformed(origin, "unreadable pr")
val paymentRequest = when (val res = PaymentRequest.read(pr)) {
is Try.Success -> res.result
is Try.Failure -> throw LnurlError.Pay.Invoice.Malformed(origin, res.error.message ?: res.error::class.toString())
}

val successAction = parseSuccessAction(origin, json)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ sealed class IncomingOriginData {
fun deserialize(typeVersion: IncomingOriginTypeVersion, blob: ByteArray): IncomingPayment.Origin = decodeBlob(blob) { json, format ->
when (typeVersion) {
IncomingOriginTypeVersion.KEYSEND_V0 -> IncomingPayment.Origin.KeySend
IncomingOriginTypeVersion.INVOICE_V0 -> format.decodeFromString<Invoice.V0>(json).let { IncomingPayment.Origin.Invoice(PaymentRequest.read(it.paymentRequest)) }
IncomingOriginTypeVersion.INVOICE_V0 -> format.decodeFromString<Invoice.V0>(json).let { IncomingPayment.Origin.Invoice(PaymentRequest.read(it.paymentRequest).get()) }
IncomingOriginTypeVersion.SWAPIN_V0 -> format.decodeFromString<SwapIn.V0>(json).let { IncomingPayment.Origin.SwapIn(it.address) }
IncomingOriginTypeVersion.ONCHAIN_V0 -> format.decodeFromString<OnChain.V0>(json).let {
IncomingPayment.Origin.OnChain(TxId(it.txId), it.outpoints.toSet())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ sealed class OutgoingDetailsData {
@Suppress("DEPRECATION")
fun deserialize(typeVersion: OutgoingDetailsTypeVersion, blob: ByteArray): LightningOutgoingPayment.Details? = DbTypesHelper.decodeBlob(blob) { json, format ->
when (typeVersion) {
OutgoingDetailsTypeVersion.NORMAL_V0 -> format.decodeFromString<Normal.V0>(json).let { LightningOutgoingPayment.Details.Normal(PaymentRequest.read(it.paymentRequest)) }
OutgoingDetailsTypeVersion.NORMAL_V0 -> format.decodeFromString<Normal.V0>(json).let { LightningOutgoingPayment.Details.Normal(PaymentRequest.read(it.paymentRequest).get()) }
OutgoingDetailsTypeVersion.KEYSEND_V0 -> format.decodeFromString<KeySend.V0>(json).let { LightningOutgoingPayment.Details.KeySend(it.preimage) }
OutgoingDetailsTypeVersion.SWAPOUT_V0 -> format.decodeFromString<SwapOut.V0>(json).let { LightningOutgoingPayment.Details.SwapOut(it.address, PaymentRequest.read(it.paymentRequest), it.swapOutFee) }
OutgoingDetailsTypeVersion.SWAPOUT_V0 -> format.decodeFromString<SwapOut.V0>(json).let { LightningOutgoingPayment.Details.SwapOut(it.address, PaymentRequest.read(it.paymentRequest).get(), it.swapOutFee) }
OutgoingDetailsTypeVersion.CLOSING_V0 -> null
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import fr.acinq.bitcoin.*
import fr.acinq.bitcoin.utils.Either
import fr.acinq.lightning.NodeParams
import fr.acinq.lightning.payment.PaymentRequest
import fr.acinq.lightning.utils.Try
import fr.acinq.lightning.utils.sat
import fr.acinq.phoenix.data.*
import io.ktor.http.*
Expand Down Expand Up @@ -70,10 +71,9 @@ object Parser {
/** Reads a payment request after stripping prefixes. Return null if input is invalid. */
fun readPaymentRequest(
input: String
): PaymentRequest? = try {
PaymentRequest.read(trimMatchingPrefix(removeExcessInput(input), lightningPrefixes))
} catch (t: Throwable) {
null
): PaymentRequest? = when (val res = PaymentRequest.read(trimMatchingPrefix(removeExcessInput(input), lightningPrefixes))) {
is Try.Success -> res.get()
is Try.Failure -> null
}

/**
Expand Down Expand Up @@ -117,10 +117,9 @@ object Parser {
val label = url.parameters["label"]
val message = url.parameters["message"]
val lightning = url.parameters["lightning"]?.let {
try {
PaymentRequest.read(it)
} catch (e: Exception) {
null
when (val res = PaymentRequest.read(it)) {
is Try.Success -> res.get()
is Try.Failure -> null
}
}
val otherParams = ParametersBuilder().apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class IncomingPaymentDbTypeVersionTest {
val channelId1 = ByteVector32.fromValidHex("3b6208285563c9adb009781acf1626f1c2a3b1a3492d5ec312ead8282c7ad6da")
val address1 = "tb1q97tpc0y4rvdnu9wm7nu354lmmzdm8du228u3g4"
val invoice1 =
PaymentRequest.read("lntb1500n1ps9u963pp5llphsu6evgmzgk8g2e73su44wn6txmwywdzwvtdwzrt9pqxc9f5sdpzxysy2umswfjhxum0yppk76twypgxzmnwvycqp7xqrrss9qy9qsqsp5qa7092geq6ptp24uzlfw0vj3w4whh2zuc9rquwca69acwx5khckqvslyw2n6dallc868vxu3uueyhw6pe00cmluynv7ca4tknz7g274rp9ucwqpx5ydejsmzl4xpegqtemcq6vwvu8alpxttlj82e7j26gspfj06gn")
PaymentRequest.read("lntb1500n1ps9u963pp5llphsu6evgmzgk8g2e73su44wn6txmwywdzwvtdwzrt9pqxc9f5sdpzxysy2umswfjhxum0yppk76twypgxzmnwvycqp7xqrrss9qy9qsqsp5qa7092geq6ptp24uzlfw0vj3w4whh2zuc9rquwca69acwx5khckqvslyw2n6dallc868vxu3uueyhw6pe00cmluynv7ca4tknz7g274rp9ucwqpx5ydejsmzl4xpegqtemcq6vwvu8alpxttlj82e7j26gspfj06gn").get()

@Test
fun incoming_origin_invoice() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class OutgoingPaymentDbTypeVersionTest {
val address1 = "tb1q97tpc0y4rvdnu9wm7nu354lmmzdm8du228u3g4"
val preimage1 = randomBytes32()
val paymentRequest1 =
PaymentRequest.read("lntb1500n1ps9utezpp5xjfvpvgg3zykv2kdd9yws86xw5ww2kr60h9yphth2h6fly87a9gqdpzxysy2umswfjhxum0yppk76twypgxzmnwvycqp7xqrrss9qy9qsqsp5vm25lch9spq2m9fxqrgcxq0mxrgaehstd9javflyadsle5d97p9qmu9zsjn7l59lmps3568tz9ppla4xhawjptjyrw32jed84fe75z0ka0kmnntc9la95acvc0mjav6rdv5037y6zq9e0eqhenlt8y0yh8cpj467cl")
PaymentRequest.read("lntb1500n1ps9utezpp5xjfvpvgg3zykv2kdd9yws86xw5ww2kr60h9yphth2h6fly87a9gqdpzxysy2umswfjhxum0yppk76twypgxzmnwvycqp7xqrrss9qy9qsqsp5vm25lch9spq2m9fxqrgcxq0mxrgaehstd9javflyadsle5d97p9qmu9zsjn7l59lmps3568tz9ppla4xhawjptjyrw32jed84fe75z0ka0kmnntc9la95acvc0mjav6rdv5037y6zq9e0eqhenlt8y0yh8cpj467cl").get()

@Test
fun outgoing_details_normal() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class SqlitePaymentsDatabaseTest {
@Test
fun incoming__is_expired() = runTest {
val expiredInvoice =
PaymentRequest.read("lntb1p0ufamxpp5l23zy5f8h2dcr8hxynptkcyuzdygy36pz76hgayp7n9q45a3cwuqdqqxqyjw5q9qtzqqqqqq9qsqsp5vusneyeywvawt4d7sslx3kx0eh7kk68l7j26qr0ge7z04lxhe5ssrzjqwfn3p9278ttzzpe0e00uhyxhned3j5d9acqak5emwfpflp8z2cnfluw6cwxn8wdcyqqqqlgqqqqqeqqjqmjvx0y3cfw54syp4jqw6jlj73qt97vxftjd3w3ywx6v2jqkdx9uxw3hk9qq6st9qyfpu3nzrpefwye63vmnyyzn6z8n7nkqsjj6lsaspu2p3mm")
PaymentRequest.read("lntb1p0ufamxpp5l23zy5f8h2dcr8hxynptkcyuzdygy36pz76hgayp7n9q45a3cwuqdqqxqyjw5q9qtzqqqqqq9qsqsp5vusneyeywvawt4d7sslx3kx0eh7kk68l7j26qr0ge7z04lxhe5ssrzjqwfn3p9278ttzzpe0e00uhyxhned3j5d9acqak5emwfpflp8z2cnfluw6cwxn8wdcyqqqqlgqqqqqeqqjqmjvx0y3cfw54syp4jqw6jlj73qt97vxftjd3w3ywx6v2jqkdx9uxw3hk9qq6st9qyfpu3nzrpefwye63vmnyyzn6z8n7nkqsjj6lsaspu2p3mm").get()
db.addIncomingPayment(preimage1, IncomingPayment.Origin.Invoice(expiredInvoice), 0)
db.receivePayment(paymentHash1, receivedWith1, 10)
assertTrue(db.getIncomingPayment(paymentHash1)!!.isExpired())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class ParserTest {
"bitcoin:bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4?foo=bar&lightning=lntb15u1p05vazrpp5apz75ghtq3ynmc5qm98tsgucmsav44fyffpguhzdep2kcgkfme4sdq4xysyymr0vd4kzcmrd9hx7cqp2xqrrss9qy9qsqsp5v4hqr48qe0u7al6lxwdpmp3w6k7evjdavm0lh7arpv3qaf038s5st2d8k8vvmxyav2wkfym9jp4mk64srmswgh7l6sqtq7l4xl3nknf8snltamvpw5p3yl9nxg0ax9k0698rr94qx6unrv8yhccmh4z9ghcq77hxps" to Either.Right(
BitcoinUri(
chain = NodeParams.Chain.Mainnet, address = "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4",
paymentRequest = PaymentRequest.read("lntb15u1p05vazrpp5apz75ghtq3ynmc5qm98tsgucmsav44fyffpguhzdep2kcgkfme4sdq4xysyymr0vd4kzcmrd9hx7cqp2xqrrss9qy9qsqsp5v4hqr48qe0u7al6lxwdpmp3w6k7evjdavm0lh7arpv3qaf038s5st2d8k8vvmxyav2wkfym9jp4mk64srmswgh7l6sqtq7l4xl3nknf8snltamvpw5p3yl9nxg0ax9k0698rr94qx6unrv8yhccmh4z9ghcq77hxps"),
paymentRequest = PaymentRequest.read("lntb15u1p05vazrpp5apz75ghtq3ynmc5qm98tsgucmsav44fyffpguhzdep2kcgkfme4sdq4xysyymr0vd4kzcmrd9hx7cqp2xqrrss9qy9qsqsp5v4hqr48qe0u7al6lxwdpmp3w6k7evjdavm0lh7arpv3qaf038s5st2d8k8vvmxyav2wkfym9jp4mk64srmswgh7l6sqtq7l4xl3nknf8snltamvpw5p3yl9nxg0ax9k0698rr94qx6unrv8yhccmh4z9ghcq77hxps").get(),
ignoredParams = ParametersBuilder().apply { set("foo", "bar") }.build()
)
),
Expand Down

0 comments on commit 1309372

Please sign in to comment.