mirror of
https://github.com/ACINQ/eclair.git
synced 2024-11-19 01:43:22 +01:00
Cleanup of RouteBlinding feature (#2856)
RouteBlinding is not an invoice feature.
This commit is contained in:
parent
bbd52fab02
commit
b73a009a1d
@ -249,7 +249,7 @@ object Features {
|
|||||||
val mandatory = 22
|
val mandatory = 22
|
||||||
}
|
}
|
||||||
|
|
||||||
case object RouteBlinding extends Feature with InitFeature with NodeFeature with Bolt11Feature {
|
case object RouteBlinding extends Feature with InitFeature with NodeFeature {
|
||||||
val rfcName = "option_route_blinding"
|
val rfcName = "option_route_blinding"
|
||||||
val mandatory = 24
|
val mandatory = 24
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,6 @@ object Bolt11Invoice {
|
|||||||
paymentMetadata: Option[ByteVector] = None,
|
paymentMetadata: Option[ByteVector] = None,
|
||||||
features: Features[Bolt11Feature] = defaultFeatures): Bolt11Invoice = {
|
features: Features[Bolt11Feature] = defaultFeatures): Bolt11Invoice = {
|
||||||
require(features.hasFeature(Features.PaymentSecret, Some(FeatureSupport.Mandatory)), "invoices must require a payment secret")
|
require(features.hasFeature(Features.PaymentSecret, Some(FeatureSupport.Mandatory)), "invoices must require a payment secret")
|
||||||
require(!features.hasFeature(Features.RouteBlinding), "bolt11 invoices cannot use route blinding")
|
|
||||||
val prefix = prefixes(chainHash)
|
val prefix = prefixes(chainHash)
|
||||||
val tags = {
|
val tags = {
|
||||||
val defaultTags = List(
|
val defaultTags = List(
|
||||||
|
@ -47,11 +47,7 @@ case class Bolt12Invoice(records: TlvStream[InvoiceTlv]) extends Invoice {
|
|||||||
val description: Option[String] = invoiceRequest.offer.description
|
val description: Option[String] = invoiceRequest.offer.description
|
||||||
override val createdAt: TimestampSecond = records.get[InvoiceCreatedAt].get.timestamp
|
override val createdAt: TimestampSecond = records.get[InvoiceCreatedAt].get.timestamp
|
||||||
override val relativeExpiry: FiniteDuration = FiniteDuration(records.get[InvoiceRelativeExpiry].map(_.seconds).getOrElse(DEFAULT_EXPIRY_SECONDS), TimeUnit.SECONDS)
|
override val relativeExpiry: FiniteDuration = FiniteDuration(records.get[InvoiceRelativeExpiry].map(_.seconds).getOrElse(DEFAULT_EXPIRY_SECONDS), TimeUnit.SECONDS)
|
||||||
override val features: Features[InvoiceFeature] = {
|
override val features: Features[InvoiceFeature] = records.get[InvoiceFeatures].map(_.features.invoiceFeatures()).getOrElse(Features.empty)
|
||||||
val f = records.get[InvoiceFeatures].map(_.features.invoiceFeatures()).getOrElse(Features.empty)
|
|
||||||
// We add invoice features that are implicitly required for Bolt 12 (the spec doesn't allow explicitly setting them).
|
|
||||||
f.add(Features.VariableLengthOnion, FeatureSupport.Mandatory).add(Features.RouteBlinding, FeatureSupport.Mandatory)
|
|
||||||
}
|
|
||||||
val blindedPaths: Seq[PaymentBlindedRoute] = records.get[InvoicePaths].get.paths.zip(records.get[InvoiceBlindedPay].get.paymentInfo).map { case (route, info) => PaymentBlindedRoute(route, info) }
|
val blindedPaths: Seq[PaymentBlindedRoute] = records.get[InvoicePaths].get.paths.zip(records.get[InvoiceBlindedPay].get.paymentInfo).map { case (route, info) => PaymentBlindedRoute(route, info) }
|
||||||
val fallbacks: Option[Seq[FallbackAddress]] = records.get[InvoiceFallbacks].map(_.addresses)
|
val fallbacks: Option[Seq[FallbackAddress]] = records.get[InvoiceFallbacks].map(_.addresses)
|
||||||
val signature: ByteVector64 = records.get[Signature].get.signature
|
val signature: ByteVector64 = records.get[Signature].get.signature
|
||||||
@ -172,11 +168,7 @@ case class MinimalBolt12Invoice(records: TlvStream[InvoiceTlv]) extends Invoice
|
|||||||
val description: Option[String] = records.get[OfferDescription].map(_.description)
|
val description: Option[String] = records.get[OfferDescription].map(_.description)
|
||||||
override val createdAt: TimestampSecond = records.get[InvoiceCreatedAt].get.timestamp
|
override val createdAt: TimestampSecond = records.get[InvoiceCreatedAt].get.timestamp
|
||||||
override val relativeExpiry: FiniteDuration = FiniteDuration(records.get[InvoiceRelativeExpiry].map(_.seconds).getOrElse(Bolt12Invoice.DEFAULT_EXPIRY_SECONDS), TimeUnit.SECONDS)
|
override val relativeExpiry: FiniteDuration = FiniteDuration(records.get[InvoiceRelativeExpiry].map(_.seconds).getOrElse(Bolt12Invoice.DEFAULT_EXPIRY_SECONDS), TimeUnit.SECONDS)
|
||||||
override val features: Features[InvoiceFeature] = {
|
override val features: Features[InvoiceFeature] = records.get[InvoiceFeatures].map(_.features.invoiceFeatures()).getOrElse(Features[InvoiceFeature](Features.BasicMultiPartPayment -> FeatureSupport.Optional))
|
||||||
val f = records.get[InvoiceFeatures].map(_.features.invoiceFeatures()).getOrElse(Features[InvoiceFeature](Features.BasicMultiPartPayment -> FeatureSupport.Optional))
|
|
||||||
// We add invoice features that are implicitly required for Bolt 12 (the spec doesn't allow explicitly setting them).
|
|
||||||
f.add(Features.VariableLengthOnion, FeatureSupport.Mandatory).add(Features.RouteBlinding, FeatureSupport.Mandatory)
|
|
||||||
}
|
|
||||||
|
|
||||||
override def toString: String = {
|
override def toString: String = {
|
||||||
val data = OfferCodecs.invoiceTlvCodec.encode(records).require.bytes
|
val data = OfferCodecs.invoiceTlvCodec.encode(records).require.bytes
|
||||||
|
@ -345,7 +345,7 @@ object MultiPartHandler {
|
|||||||
expirySeconds = Some(expirySeconds),
|
expirySeconds = Some(expirySeconds),
|
||||||
extraHops = r.extraHops,
|
extraHops = r.extraHops,
|
||||||
paymentMetadata = Some(paymentMetadata),
|
paymentMetadata = Some(paymentMetadata),
|
||||||
features = featuresTrampolineOpt.remove(Features.RouteBlinding)
|
features = featuresTrampolineOpt
|
||||||
)
|
)
|
||||||
context.log.debug("generated invoice={} from amount={}", invoice.toString, r.amount_opt)
|
context.log.debug("generated invoice={} from amount={}", invoice.toString, r.amount_opt)
|
||||||
nodeParams.db.payments.addIncomingPayment(invoice, paymentPreimage, r.paymentType)
|
nodeParams.db.payments.addIncomingPayment(invoice, paymentPreimage, r.paymentType)
|
||||||
|
@ -320,7 +320,7 @@ class JsonSerializersSpec extends TestKitBaseClass with AnyFunSuiteLike with Mat
|
|||||||
test("Bolt 12 invoice") {
|
test("Bolt 12 invoice") {
|
||||||
val ref = "lni1qqsf4h8fsnpjkj057gjg9c3eqhv889440xh0z6f5kng9vsaad8pgq7sgqsdjuqsqpgxk66twd9kkzmpqdanxvetjzcss83y2e9lqnu7tht4ntvp24fksw26hwf5yrg6dyk2jz472efs2rjh42qsxlc5vp2m0rvmjcxn2y34wv0m5lyc7sdj7zksgn35dvxgqqqqqqqzjqsdjupkjtqssx05572ha26x39rczan5yft22pgwa72jw8gytavkm5ydn7yf5kpgh5zsq83y2e9lqnu7tht4ntvp24fksw26hwf5yrg6dyk2jz472efs2rjh4q2rd3ny0elv9m7mh38xxwe6ypfheeqeqlwgft05r6dhc50gtw0nv2qgrrl9x2qzzqvwukam32mhkdqrvwwcp5l6jcnnnezdq69vz8gdvvgmsqwk3efqf3f6gmf0ul63940awz429rdhhsts86s0r30e5nffwhrqw90xgxf7f60sm7tcclvyqwz7cer5q9223madstdy2p5q6y8qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqf2qheqqqqq2gprrgshynfszqyk2sgpvkrnmq53kv7r52rpnmtmd9ukredsnygsnymsurdy6e9la6l4hyz4qgxewqmftqggrcj9vjlsf709m46e4kq425mg89dthy6zp5dxjt9fp2l9v5c9pet6lqsx4k5r7rsld3hhe87psyy5cnhhzt4dz838f75734mted7pdsrflpvys23tkafmhctf3musnsaa42h6qjdggyqlhtevutzzpzlnwd8alq"
|
val ref = "lni1qqsf4h8fsnpjkj057gjg9c3eqhv889440xh0z6f5kng9vsaad8pgq7sgqsdjuqsqpgxk66twd9kkzmpqdanxvetjzcss83y2e9lqnu7tht4ntvp24fksw26hwf5yrg6dyk2jz472efs2rjh42qsxlc5vp2m0rvmjcxn2y34wv0m5lyc7sdj7zksgn35dvxgqqqqqqqzjqsdjupkjtqssx05572ha26x39rczan5yft22pgwa72jw8gytavkm5ydn7yf5kpgh5zsq83y2e9lqnu7tht4ntvp24fksw26hwf5yrg6dyk2jz472efs2rjh4q2rd3ny0elv9m7mh38xxwe6ypfheeqeqlwgft05r6dhc50gtw0nv2qgrrl9x2qzzqvwukam32mhkdqrvwwcp5l6jcnnnezdq69vz8gdvvgmsqwk3efqf3f6gmf0ul63940awz429rdhhsts86s0r30e5nffwhrqw90xgxf7f60sm7tcclvyqwz7cer5q9223madstdy2p5q6y8qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqf2qheqqqqq2gprrgshynfszqyk2sgpvkrnmq53kv7r52rpnmtmd9ukredsnygsnymsurdy6e9la6l4hyz4qgxewqmftqggrcj9vjlsf709m46e4kq425mg89dthy6zp5dxjt9fp2l9v5c9pet6lqsx4k5r7rsld3hhe87psyy5cnhhzt4dz838f75734mted7pdsrflpvys23tkafmhctf3musnsaa42h6qjdggyqlhtevutzzpzlnwd8alq"
|
||||||
val pr = Invoice.fromString(ref).get
|
val pr = Invoice.fromString(ref).get
|
||||||
JsonSerializers.serialization.write(pr)(JsonSerializers.formats) shouldBe """{"amount":456001234,"nodeId":"03c48ac97e09f3cbbaeb35b02aaa6d072b57726841a34d25952157caca60a1caf5","paymentHash":"2cb0e7b052366787450c33daf6d2f2c3cb6132221326e1c1b49ac97fdd7eb720","description":"minimal offer","features":{"activated":{"var_onion_optin":"mandatory","option_route_blinding":"mandatory"},"unknown":[]},"blindedPaths":[{"introductionNodeId":"03c48ac97e09f3cbbaeb35b02aaa6d072b57726841a34d25952157caca60a1caf5","blindedNodeIds":["031fca650042031dcb777156ef66806c73b01a7f52c4e73c89a0d15823a1ac6237"]}],"createdAt":1665412681,"expiresAt":1665412981,"serialized":"lni1qqsf4h8fsnpjkj057gjg9c3eqhv889440xh0z6f5kng9vsaad8pgq7sgqsdjuqsqpgxk66twd9kkzmpqdanxvetjzcss83y2e9lqnu7tht4ntvp24fksw26hwf5yrg6dyk2jz472efs2rjh42qsxlc5vp2m0rvmjcxn2y34wv0m5lyc7sdj7zksgn35dvxgqqqqqqqzjqsdjupkjtqssx05572ha26x39rczan5yft22pgwa72jw8gytavkm5ydn7yf5kpgh5zsq83y2e9lqnu7tht4ntvp24fksw26hwf5yrg6dyk2jz472efs2rjh4q2rd3ny0elv9m7mh38xxwe6ypfheeqeqlwgft05r6dhc50gtw0nv2qgrrl9x2qzzqvwukam32mhkdqrvwwcp5l6jcnnnezdq69vz8gdvvgmsqwk3efqf3f6gmf0ul63940awz429rdhhsts86s0r30e5nffwhrqw90xgxf7f60sm7tcclvyqwz7cer5q9223madstdy2p5q6y8qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqf2qheqqqqq2gprrgshynfszqyk2sgpvkrnmq53kv7r52rpnmtmd9ukredsnygsnymsurdy6e9la6l4hyz4qgxewqmftqggrcj9vjlsf709m46e4kq425mg89dthy6zp5dxjt9fp2l9v5c9pet6lqsx4k5r7rsld3hhe87psyy5cnhhzt4dz838f75734mted7pdsrflpvys23tkafmhctf3musnsaa42h6qjdggyqlhtevutzzpzlnwd8alq"}"""
|
JsonSerializers.serialization.write(pr)(JsonSerializers.formats) shouldBe """{"amount":456001234,"nodeId":"03c48ac97e09f3cbbaeb35b02aaa6d072b57726841a34d25952157caca60a1caf5","paymentHash":"2cb0e7b052366787450c33daf6d2f2c3cb6132221326e1c1b49ac97fdd7eb720","description":"minimal offer","features":{"activated":{},"unknown":[]},"blindedPaths":[{"introductionNodeId":"03c48ac97e09f3cbbaeb35b02aaa6d072b57726841a34d25952157caca60a1caf5","blindedNodeIds":["031fca650042031dcb777156ef66806c73b01a7f52c4e73c89a0d15823a1ac6237"]}],"createdAt":1665412681,"expiresAt":1665412981,"serialized":"lni1qqsf4h8fsnpjkj057gjg9c3eqhv889440xh0z6f5kng9vsaad8pgq7sgqsdjuqsqpgxk66twd9kkzmpqdanxvetjzcss83y2e9lqnu7tht4ntvp24fksw26hwf5yrg6dyk2jz472efs2rjh42qsxlc5vp2m0rvmjcxn2y34wv0m5lyc7sdj7zksgn35dvxgqqqqqqqzjqsdjupkjtqssx05572ha26x39rczan5yft22pgwa72jw8gytavkm5ydn7yf5kpgh5zsq83y2e9lqnu7tht4ntvp24fksw26hwf5yrg6dyk2jz472efs2rjh4q2rd3ny0elv9m7mh38xxwe6ypfheeqeqlwgft05r6dhc50gtw0nv2qgrrl9x2qzzqvwukam32mhkdqrvwwcp5l6jcnnnezdq69vz8gdvvgmsqwk3efqf3f6gmf0ul63940awz429rdhhsts86s0r30e5nffwhrqw90xgxf7f60sm7tcclvyqwz7cer5q9223madstdy2p5q6y8qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqf2qheqqqqq2gprrgshynfszqyk2sgpvkrnmq53kv7r52rpnmtmd9ukredsnygsnymsurdy6e9la6l4hyz4qgxewqmftqggrcj9vjlsf709m46e4kq425mg89dthy6zp5dxjt9fp2l9v5c9pet6lqsx4k5r7rsld3hhe87psyy5cnhhzt4dz838f75734mted7pdsrflpvys23tkafmhctf3musnsaa42h6qjdggyqlhtevutzzpzlnwd8alq"}"""
|
||||||
}
|
}
|
||||||
|
|
||||||
test("GlobalBalance serializer") {
|
test("GlobalBalance serializer") {
|
||||||
|
@ -652,7 +652,7 @@ class Bolt11InvoiceSpec extends AnyFunSuite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test("no unknown feature in invoice") {
|
test("no unknown feature in invoice") {
|
||||||
val invoiceFeatures = TestConstants.Alice.nodeParams.features.bolt11Features().remove(RouteBlinding)
|
val invoiceFeatures = TestConstants.Alice.nodeParams.features.bolt11Features()
|
||||||
assert(invoiceFeatures.unknown.nonEmpty)
|
assert(invoiceFeatures.unknown.nonEmpty)
|
||||||
val invoice = Bolt11Invoice(Block.LivenetGenesisBlock.hash, Some(123 msat), ByteVector32.One, priv, Left("Some invoice"), CltvExpiryDelta(18), features = invoiceFeatures)
|
val invoice = Bolt11Invoice(Block.LivenetGenesisBlock.hash, Some(123 msat), ByteVector32.One, priv, Left("Some invoice"), CltvExpiryDelta(18), features = invoiceFeatures)
|
||||||
assert(invoice.features == Features(PaymentSecret -> Mandatory, BasicMultiPartPayment -> Optional, PaymentMetadata -> Optional, VariableLengthOnion -> Mandatory))
|
assert(invoice.features == Features(PaymentSecret -> Mandatory, BasicMultiPartPayment -> Optional, PaymentMetadata -> Optional, VariableLengthOnion -> Mandatory))
|
||||||
|
@ -213,7 +213,7 @@ class Bolt12InvoiceSpec extends AnyFunSuite {
|
|||||||
val chain = Block.TestnetGenesisBlock.hash
|
val chain = Block.TestnetGenesisBlock.hash
|
||||||
val amount = 123456 msat
|
val amount = 123456 msat
|
||||||
val description = "invoice with many fields"
|
val description = "invoice with many fields"
|
||||||
val features = Features[Feature](Features.VariableLengthOnion -> FeatureSupport.Mandatory, Features.RouteBlinding -> FeatureSupport.Mandatory)
|
val features = Features.empty
|
||||||
val issuer = "alice"
|
val issuer = "alice"
|
||||||
val nodeKey = PrivateKey(hex"998cf8ecab46f949bb960813b79d3317cabf4193452a211795cd8af1b9a25d90")
|
val nodeKey = PrivateKey(hex"998cf8ecab46f949bb960813b79d3317cabf4193452a211795cd8af1b9a25d90")
|
||||||
val path = createPaymentBlindedRoute(nodeKey.publicKey, PrivateKey(hex"f0442c17bdd2cefe4a4ede210f163b068bb3fea6113ffacea4f322de7aa9737b"), hex"76030536ba732cdc4e7bb0a883750bab2e88cb3dddd042b1952c44b4849c86bb").copy(paymentInfo = PaymentInfo(2345 msat, 765, CltvExpiryDelta(324), 1000 msat, amount, Features.empty))
|
val path = createPaymentBlindedRoute(nodeKey.publicKey, PrivateKey(hex"f0442c17bdd2cefe4a4ede210f163b068bb3fea6113ffacea4f322de7aa9737b"), hex"76030536ba732cdc4e7bb0a883750bab2e88cb3dddd042b1952c44b4849c86bb").copy(paymentInfo = PaymentInfo(2345 msat, 765, CltvExpiryDelta(324), 1000 msat, amount, Features.empty))
|
||||||
|
@ -171,7 +171,6 @@ class MultiPartHandlerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
sender.send(handlerWithRouteBlinding, ReceiveOfferPayment(sender.ref, privKey, invoiceReq, createEmptyReceivingRoute(), router.ref, preimage, pathId))
|
sender.send(handlerWithRouteBlinding, ReceiveOfferPayment(sender.ref, privKey, invoiceReq, createEmptyReceivingRoute(), router.ref, preimage, pathId))
|
||||||
router.expectNoMessage(50 millis)
|
router.expectNoMessage(50 millis)
|
||||||
val invoice = sender.expectMsgType[CreateInvoiceActor.InvoiceCreated].invoice
|
val invoice = sender.expectMsgType[CreateInvoiceActor.InvoiceCreated].invoice
|
||||||
assert(invoice.features.hasFeature(RouteBlinding, Some(Mandatory)))
|
|
||||||
// Offer invoices shouldn't be stored in the DB until we receive a payment for it.
|
// Offer invoices shouldn't be stored in the DB until we receive a payment for it.
|
||||||
assert(nodeParams.db.payments.getIncomingPayment(invoice.paymentHash).isEmpty)
|
assert(nodeParams.db.payments.getIncomingPayment(invoice.paymentHash).isEmpty)
|
||||||
|
|
||||||
@ -290,7 +289,6 @@ class MultiPartHandlerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
assert(invoice.amount == 25_000.msat)
|
assert(invoice.amount == 25_000.msat)
|
||||||
assert(invoice.nodeId == privKey.publicKey)
|
assert(invoice.nodeId == privKey.publicKey)
|
||||||
assert(invoice.blindedPaths.nonEmpty)
|
assert(invoice.blindedPaths.nonEmpty)
|
||||||
assert(invoice.features.hasFeature(RouteBlinding, Some(Mandatory)))
|
|
||||||
assert(invoice.description.contains("a blinded coffee please"))
|
assert(invoice.description.contains("a blinded coffee please"))
|
||||||
assert(invoice.invoiceRequest.offer == offer)
|
assert(invoice.invoiceRequest.offer == offer)
|
||||||
assert(invoice.blindedPaths.length == 3)
|
assert(invoice.blindedPaths.length == 3)
|
||||||
@ -472,7 +470,6 @@ class MultiPartHandlerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
|
|
||||||
sender.send(handlerWithRouteBlinding, ReceiveStandardPayment(sender.ref, Some(1000 msat), Left("non blinded payment")))
|
sender.send(handlerWithRouteBlinding, ReceiveStandardPayment(sender.ref, Some(1000 msat), Left("non blinded payment")))
|
||||||
val invoice = sender.expectMsgType[Bolt11Invoice]
|
val invoice = sender.expectMsgType[Bolt11Invoice]
|
||||||
assert(!invoice.features.hasFeature(RouteBlinding))
|
|
||||||
|
|
||||||
val packet = createBlindedPacket(1000 msat, invoice.paymentHash, defaultExpiry, CltvExpiry(nodeParams.currentBlockHeight), randomBytes32())
|
val packet = createBlindedPacket(1000 msat, invoice.paymentHash, defaultExpiry, CltvExpiry(nodeParams.currentBlockHeight), randomBytes32())
|
||||||
sender.send(handlerWithRouteBlinding, packet)
|
sender.send(handlerWithRouteBlinding, packet)
|
||||||
@ -492,7 +489,6 @@ class MultiPartHandlerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
val invoiceReq = InvoiceRequest(offer, 5000 msat, 1, featuresWithRouteBlinding.bolt12Features(), randomKey(), Block.RegtestGenesisBlock.hash)
|
val invoiceReq = InvoiceRequest(offer, 5000 msat, 1, featuresWithRouteBlinding.bolt12Features(), randomKey(), Block.RegtestGenesisBlock.hash)
|
||||||
sender.send(handlerWithRouteBlinding, ReceiveOfferPayment(sender.ref, nodeKey, invoiceReq, createEmptyReceivingRoute(), TestProbe().ref, randomBytes32(), randomBytes32()))
|
sender.send(handlerWithRouteBlinding, ReceiveOfferPayment(sender.ref, nodeKey, invoiceReq, createEmptyReceivingRoute(), TestProbe().ref, randomBytes32(), randomBytes32()))
|
||||||
val invoice = sender.expectMsgType[CreateInvoiceActor.InvoiceCreated].invoice
|
val invoice = sender.expectMsgType[CreateInvoiceActor.InvoiceCreated].invoice
|
||||||
assert(invoice.features.hasFeature(RouteBlinding, Some(Mandatory)))
|
|
||||||
|
|
||||||
val add = UpdateAddHtlc(ByteVector32.One, 0, 5000 msat, invoice.paymentHash, defaultExpiry, TestConstants.emptyOnionPacket, None)
|
val add = UpdateAddHtlc(ByteVector32.One, 0, 5000 msat, invoice.paymentHash, defaultExpiry, TestConstants.emptyOnionPacket, None)
|
||||||
sender.send(handlerWithMpp, IncomingPaymentPacket.FinalPacket(add, FinalPayload.Standard.createPayload(add.amountMsat, add.amountMsat, add.cltvExpiry, randomBytes32(), None)))
|
sender.send(handlerWithMpp, IncomingPaymentPacket.FinalPacket(add, FinalPayload.Standard.createPayload(add.amountMsat, add.amountMsat, add.cltvExpiry, randomBytes32(), None)))
|
||||||
@ -511,7 +507,6 @@ class MultiPartHandlerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
val pathId = randomBytes32()
|
val pathId = randomBytes32()
|
||||||
sender.send(handlerWithRouteBlinding, ReceiveOfferPayment(sender.ref, nodeKey, invoiceReq, createEmptyReceivingRoute(), TestProbe().ref, preimage, pathId))
|
sender.send(handlerWithRouteBlinding, ReceiveOfferPayment(sender.ref, nodeKey, invoiceReq, createEmptyReceivingRoute(), TestProbe().ref, preimage, pathId))
|
||||||
val invoice = sender.expectMsgType[CreateInvoiceActor.InvoiceCreated].invoice
|
val invoice = sender.expectMsgType[CreateInvoiceActor.InvoiceCreated].invoice
|
||||||
assert(invoice.features.hasFeature(RouteBlinding, Some(Mandatory)))
|
|
||||||
assert(nodeParams.db.payments.getIncomingPayment(invoice.paymentHash).isEmpty)
|
assert(nodeParams.db.payments.getIncomingPayment(invoice.paymentHash).isEmpty)
|
||||||
|
|
||||||
val packet = createBlindedPacket(5000 msat, invoice.paymentHash, defaultExpiry, CltvExpiry(nodeParams.currentBlockHeight), pathId)
|
val packet = createBlindedPacket(5000 msat, invoice.paymentHash, defaultExpiry, CltvExpiry(nodeParams.currentBlockHeight), pathId)
|
||||||
@ -535,7 +530,6 @@ class MultiPartHandlerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
val invoiceReq = InvoiceRequest(offer, 5000 msat, 1, featuresWithRouteBlinding.bolt12Features(), randomKey(), Block.RegtestGenesisBlock.hash)
|
val invoiceReq = InvoiceRequest(offer, 5000 msat, 1, featuresWithRouteBlinding.bolt12Features(), randomKey(), Block.RegtestGenesisBlock.hash)
|
||||||
sender.send(handlerWithRouteBlinding, ReceiveOfferPayment(sender.ref, nodeKey, invoiceReq, createEmptyReceivingRoute(), TestProbe().ref, preimage, pathId))
|
sender.send(handlerWithRouteBlinding, ReceiveOfferPayment(sender.ref, nodeKey, invoiceReq, createEmptyReceivingRoute(), TestProbe().ref, preimage, pathId))
|
||||||
val invoice = sender.expectMsgType[CreateInvoiceActor.InvoiceCreated].invoice
|
val invoice = sender.expectMsgType[CreateInvoiceActor.InvoiceCreated].invoice
|
||||||
assert(invoice.features.hasFeature(RouteBlinding, Some(Mandatory)))
|
|
||||||
|
|
||||||
val packet = createBlindedPacket(5000 msat, invoice.paymentHash, defaultExpiry, CltvExpiry(nodeParams.currentBlockHeight), pathId)
|
val packet = createBlindedPacket(5000 msat, invoice.paymentHash, defaultExpiry, CltvExpiry(nodeParams.currentBlockHeight), pathId)
|
||||||
sender.send(handlerWithRouteBlinding, packet)
|
sender.send(handlerWithRouteBlinding, packet)
|
||||||
@ -556,7 +550,6 @@ class MultiPartHandlerSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
val pathId = randomBytes32()
|
val pathId = randomBytes32()
|
||||||
sender.send(handlerWithRouteBlinding, ReceiveOfferPayment(sender.ref, nodeKey, invoiceReq, createEmptyReceivingRoute(), TestProbe().ref, preimage, pathId))
|
sender.send(handlerWithRouteBlinding, ReceiveOfferPayment(sender.ref, nodeKey, invoiceReq, createEmptyReceivingRoute(), TestProbe().ref, preimage, pathId))
|
||||||
val invoice = sender.expectMsgType[CreateInvoiceActor.InvoiceCreated].invoice
|
val invoice = sender.expectMsgType[CreateInvoiceActor.InvoiceCreated].invoice
|
||||||
assert(invoice.features.hasFeature(RouteBlinding, Some(Mandatory)))
|
|
||||||
|
|
||||||
// We test the case where the HTLC's cltv_expiry is lower than expected and doesn't meet the min_final_expiry_delta.
|
// We test the case where the HTLC's cltv_expiry is lower than expected and doesn't meet the min_final_expiry_delta.
|
||||||
val packet = createBlindedPacket(5000 msat, invoice.paymentHash, defaultExpiry - CltvExpiryDelta(1), defaultExpiry, pathId)
|
val packet = createBlindedPacket(5000 msat, invoice.paymentHash, defaultExpiry - CltvExpiryDelta(1), defaultExpiry, pathId)
|
||||||
|
@ -54,7 +54,6 @@ class PaymentInitiatorSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
|
|
||||||
object Tags {
|
object Tags {
|
||||||
val DisableMPP = "mpp_disabled"
|
val DisableMPP = "mpp_disabled"
|
||||||
val DisableRouteBlinding = "route_blinding_disabled"
|
|
||||||
val RandomizeFinalExpiry = "random_final_expiry"
|
val RandomizeFinalExpiry = "random_final_expiry"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,14 +62,12 @@ class PaymentInitiatorSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
val featuresWithoutMpp: Features[Bolt11Feature] = Features(
|
val featuresWithoutMpp: Features[Bolt11Feature] = Features(
|
||||||
VariableLengthOnion -> Mandatory,
|
VariableLengthOnion -> Mandatory,
|
||||||
PaymentSecret -> Mandatory,
|
PaymentSecret -> Mandatory,
|
||||||
RouteBlinding -> Optional,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val featuresWithMpp: Features[Bolt11Feature] = Features(
|
val featuresWithMpp: Features[Bolt11Feature] = Features(
|
||||||
VariableLengthOnion -> Mandatory,
|
VariableLengthOnion -> Mandatory,
|
||||||
PaymentSecret -> Mandatory,
|
PaymentSecret -> Mandatory,
|
||||||
BasicMultiPartPayment -> Optional,
|
BasicMultiPartPayment -> Optional,
|
||||||
RouteBlinding -> Optional,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val featuresWithTrampoline: Features[Bolt11Feature] = Features(
|
val featuresWithTrampoline: Features[Bolt11Feature] = Features(
|
||||||
@ -80,12 +77,6 @@ class PaymentInitiatorSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
TrampolinePaymentPrototype -> Optional,
|
TrampolinePaymentPrototype -> Optional,
|
||||||
)
|
)
|
||||||
|
|
||||||
val featuresWithoutRouteBlinding: Features[Bolt11Feature] = Features(
|
|
||||||
VariableLengthOnion -> Mandatory,
|
|
||||||
PaymentSecret -> Mandatory,
|
|
||||||
BasicMultiPartPayment -> Optional,
|
|
||||||
)
|
|
||||||
|
|
||||||
case class FakePaymentFactory(payFsm: TestProbe, multiPartPayFsm: TestProbe) extends PaymentInitiator.MultiPartPaymentFactory {
|
case class FakePaymentFactory(payFsm: TestProbe, multiPartPayFsm: TestProbe) extends PaymentInitiator.MultiPartPaymentFactory {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
override def spawnOutgoingPayment(context: ActorContext, cfg: SendPaymentConfig): ActorRef = {
|
override def spawnOutgoingPayment(context: ActorContext, cfg: SendPaymentConfig): ActorRef = {
|
||||||
@ -102,8 +93,6 @@ class PaymentInitiatorSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
override def withFixture(test: OneArgTest): Outcome = {
|
override def withFixture(test: OneArgTest): Outcome = {
|
||||||
val features = if (test.tags.contains(Tags.DisableMPP)) {
|
val features = if (test.tags.contains(Tags.DisableMPP)) {
|
||||||
featuresWithoutMpp
|
featuresWithoutMpp
|
||||||
} else if (test.tags.contains(Tags.DisableRouteBlinding)) {
|
|
||||||
featuresWithoutRouteBlinding
|
|
||||||
} else {
|
} else {
|
||||||
featuresWithMpp
|
featuresWithMpp
|
||||||
}
|
}
|
||||||
@ -205,7 +194,7 @@ class PaymentInitiatorSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
test("forward single-part payment when multi-part deactivated", Tag(Tags.DisableMPP)) { f =>
|
test("forward single-part payment when multi-part deactivated", Tag(Tags.DisableMPP)) { f =>
|
||||||
import f._
|
import f._
|
||||||
val finalExpiryDelta = CltvExpiryDelta(24)
|
val finalExpiryDelta = CltvExpiryDelta(24)
|
||||||
val invoice = Bolt11Invoice(Block.LivenetGenesisBlock.hash, Some(finalAmount), paymentHash, priv_c.privateKey, Left("Some MPP invoice"), finalExpiryDelta, features = featuresWithoutRouteBlinding)
|
val invoice = Bolt11Invoice(Block.LivenetGenesisBlock.hash, Some(finalAmount), paymentHash, priv_c.privateKey, Left("Some MPP invoice"), finalExpiryDelta, features = featuresWithMpp)
|
||||||
val req = SendPaymentToNode(sender.ref, finalAmount, invoice, Nil, 1, routeParams = nodeParams.routerConf.pathFindingExperimentConf.getRandomConf().getDefaultRouteParams)
|
val req = SendPaymentToNode(sender.ref, finalAmount, invoice, Nil, 1, routeParams = nodeParams.routerConf.pathFindingExperimentConf.getRandomConf().getDefaultRouteParams)
|
||||||
assert(req.finalExpiry(nodeParams) == (finalExpiryDelta + 1).toCltvExpiry(nodeParams.currentBlockHeight))
|
assert(req.finalExpiry(nodeParams) == (finalExpiryDelta + 1).toCltvExpiry(nodeParams.currentBlockHeight))
|
||||||
sender.send(initiator, req)
|
sender.send(initiator, req)
|
||||||
@ -229,7 +218,7 @@ class PaymentInitiatorSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
|
|
||||||
test("forward multi-part payment") { f =>
|
test("forward multi-part payment") { f =>
|
||||||
import f._
|
import f._
|
||||||
val invoice = Bolt11Invoice(Block.LivenetGenesisBlock.hash, Some(finalAmount), paymentHash, priv_c.privateKey, Left("Some invoice"), CltvExpiryDelta(18), features = featuresWithoutRouteBlinding)
|
val invoice = Bolt11Invoice(Block.LivenetGenesisBlock.hash, Some(finalAmount), paymentHash, priv_c.privateKey, Left("Some invoice"), CltvExpiryDelta(18), features = featuresWithMpp)
|
||||||
val req = SendPaymentToNode(sender.ref, finalAmount + 100.msat, invoice, Nil, 1, routeParams = nodeParams.routerConf.pathFindingExperimentConf.getRandomConf().getDefaultRouteParams)
|
val req = SendPaymentToNode(sender.ref, finalAmount + 100.msat, invoice, Nil, 1, routeParams = nodeParams.routerConf.pathFindingExperimentConf.getRandomConf().getDefaultRouteParams)
|
||||||
sender.send(initiator, req)
|
sender.send(initiator, req)
|
||||||
val id = sender.expectMsgType[UUID]
|
val id = sender.expectMsgType[UUID]
|
||||||
@ -253,7 +242,7 @@ class PaymentInitiatorSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
test("forward multi-part payment with randomized final expiry", Tag(Tags.RandomizeFinalExpiry)) { f =>
|
test("forward multi-part payment with randomized final expiry", Tag(Tags.RandomizeFinalExpiry)) { f =>
|
||||||
import f._
|
import f._
|
||||||
val invoiceFinalExpiryDelta = CltvExpiryDelta(6)
|
val invoiceFinalExpiryDelta = CltvExpiryDelta(6)
|
||||||
val invoice = Bolt11Invoice(Block.LivenetGenesisBlock.hash, Some(finalAmount), paymentHash, priv_c.privateKey, Left("Some invoice"), invoiceFinalExpiryDelta, features = featuresWithoutRouteBlinding)
|
val invoice = Bolt11Invoice(Block.LivenetGenesisBlock.hash, Some(finalAmount), paymentHash, priv_c.privateKey, Left("Some invoice"), invoiceFinalExpiryDelta, features = featuresWithMpp)
|
||||||
val req = SendPaymentToNode(sender.ref, finalAmount, invoice, Nil, 1, routeParams = nodeParams.routerConf.pathFindingExperimentConf.getRandomConf().getDefaultRouteParams)
|
val req = SendPaymentToNode(sender.ref, finalAmount, invoice, Nil, 1, routeParams = nodeParams.routerConf.pathFindingExperimentConf.getRandomConf().getDefaultRouteParams)
|
||||||
sender.send(initiator, req)
|
sender.send(initiator, req)
|
||||||
val id = sender.expectMsgType[UUID]
|
val id = sender.expectMsgType[UUID]
|
||||||
@ -266,7 +255,7 @@ class PaymentInitiatorSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
|
|
||||||
test("forward multi-part payment with pre-defined route") { f =>
|
test("forward multi-part payment with pre-defined route") { f =>
|
||||||
import f._
|
import f._
|
||||||
val invoice = Bolt11Invoice(Block.LivenetGenesisBlock.hash, Some(finalAmount), paymentHash, priv_c.privateKey, Left("Some invoice"), CltvExpiryDelta(18), features = featuresWithoutRouteBlinding)
|
val invoice = Bolt11Invoice(Block.LivenetGenesisBlock.hash, Some(finalAmount), paymentHash, priv_c.privateKey, Left("Some invoice"), CltvExpiryDelta(18), features = featuresWithMpp)
|
||||||
val route = PredefinedChannelRoute(finalAmount / 2, c, Seq(channelUpdate_ab.shortChannelId, channelUpdate_bc.shortChannelId))
|
val route = PredefinedChannelRoute(finalAmount / 2, c, Seq(channelUpdate_ab.shortChannelId, channelUpdate_bc.shortChannelId))
|
||||||
val req = SendPaymentToRoute(finalAmount, invoice, Nil, route, None, None, None)
|
val req = SendPaymentToRoute(finalAmount, invoice, Nil, route, None, None, None)
|
||||||
sender.send(initiator, req)
|
sender.send(initiator, req)
|
||||||
@ -363,18 +352,6 @@ class PaymentInitiatorSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
sender.expectMsg(NoPendingPayment(PaymentIdentifier.PaymentUUID(id)))
|
sender.expectMsg(NoPendingPayment(PaymentIdentifier.PaymentUUID(id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
test("reject blinded payment when route blinding deactivated", Tag(Tags.DisableRouteBlinding)) { f =>
|
|
||||||
import f._
|
|
||||||
val invoice = createBolt12Invoice(Features(BasicMultiPartPayment -> Optional), randomKey())
|
|
||||||
val resolvedPaths = invoice.blindedPaths.map(path => ResolvedPath(path, path.route.introductionNodeId.asInstanceOf[EncodedNodeId.Plain].publicKey))
|
|
||||||
val req = SendPaymentToNode(sender.ref, finalAmount, invoice, resolvedPaths, 1, routeParams = nodeParams.routerConf.pathFindingExperimentConf.getRandomConf().getDefaultRouteParams)
|
|
||||||
sender.send(initiator, req)
|
|
||||||
val id = sender.expectMsgType[UUID]
|
|
||||||
val fail = sender.expectMsgType[PaymentFailed]
|
|
||||||
assert(fail.id == id)
|
|
||||||
assert(fail.failures == LocalFailure(finalAmount, Nil, UnsupportedFeatures(invoice.features)) :: Nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
test("forward trampoline payment") { f =>
|
test("forward trampoline payment") { f =>
|
||||||
import f._
|
import f._
|
||||||
val ignoredRoutingHints = List(List(ExtraHop(b, channelUpdate_bc.shortChannelId, feeBase = 10 msat, feeProportionalMillionths = 1, cltvExpiryDelta = CltvExpiryDelta(12))))
|
val ignoredRoutingHints = List(List(ExtraHop(b, channelUpdate_bc.shortChannelId, feeBase = 10 msat, feeProportionalMillionths = 1, cltvExpiryDelta = CltvExpiryDelta(12))))
|
||||||
@ -429,7 +406,7 @@ class PaymentInitiatorSpec extends TestKitBaseClass with FixtureAnyFunSuiteLike
|
|||||||
import f._
|
import f._
|
||||||
// This is disabled because it would let the trampoline node steal the whole payment (if malicious).
|
// This is disabled because it would let the trampoline node steal the whole payment (if malicious).
|
||||||
val routingHints = List(List(Bolt11Invoice.ExtraHop(b, channelUpdate_bc.shortChannelId, 10 msat, 100, CltvExpiryDelta(144))))
|
val routingHints = List(List(Bolt11Invoice.ExtraHop(b, channelUpdate_bc.shortChannelId, 10 msat, 100, CltvExpiryDelta(144))))
|
||||||
val invoice = Bolt11Invoice(Block.RegtestGenesisBlock.hash, None, paymentHash, priv_a.privateKey, Left("#abittooreckless"), CltvExpiryDelta(18), None, None, routingHints, features = featuresWithoutRouteBlinding)
|
val invoice = Bolt11Invoice(Block.RegtestGenesisBlock.hash, None, paymentHash, priv_a.privateKey, Left("#abittooreckless"), CltvExpiryDelta(18), None, None, routingHints, features = featuresWithMpp)
|
||||||
val trampolineFees = 21_000 msat
|
val trampolineFees = 21_000 msat
|
||||||
val req = SendTrampolinePayment(sender.ref, finalAmount, invoice, b, Seq((trampolineFees, CltvExpiryDelta(12))), routeParams = nodeParams.routerConf.pathFindingExperimentConf.getRandomConf().getDefaultRouteParams)
|
val req = SendTrampolinePayment(sender.ref, finalAmount, invoice, b, Seq((trampolineFees, CltvExpiryDelta(12))), routeParams = nodeParams.routerConf.pathFindingExperimentConf.getRandomConf().getDefaultRouteParams)
|
||||||
sender.send(initiator, req)
|
sender.send(initiator, req)
|
||||||
|
Loading…
Reference in New Issue
Block a user