@@ -63,6 +63,15 @@ class OfferManagerTestsCommon : LightningTestSuite() {
63
63
return offer
64
64
}
65
65
66
+ private fun decryptPathId (invoice : Bolt12Invoice , trampolineKey : PrivateKey ): OfferPaymentMetadata .V1 {
67
+ val blindedRoute = invoice.blindedPaths.first().route.route
68
+ assertEquals(2 , blindedRoute.encryptedPayloads.size)
69
+ val (_, nextBlinding) = RouteBlinding .decryptPayload(trampolineKey, blindedRoute.blindingKey, blindedRoute.encryptedPayloads.first()).right!!
70
+ val (lastPayload, _) = RouteBlinding .decryptPayload(TestConstants .Alice .nodeParams.nodePrivateKey, nextBlinding, blindedRoute.encryptedPayloads.last()).right!!
71
+ val pathId = RouteBlindingEncryptedData .read(lastPayload.toByteArray()).right!! .pathId!!
72
+ return OfferPaymentMetadata .fromPathId(TestConstants .Alice .nodeParams.nodeId, pathId) as OfferPaymentMetadata .V1
73
+ }
74
+
66
75
@Test
67
76
fun `pay offer through the same trampoline node` () = runSuspendTest {
68
77
// Alice and Bob use the same trampoline node.
@@ -71,17 +80,18 @@ class OfferManagerTestsCommon : LightningTestSuite() {
71
80
val offer = createOffer(aliceOfferManager, amount = 1000 .msat)
72
81
73
82
// Bob sends an invoice request to Alice.
83
+ val currentBlockHeight = 0
74
84
val payOffer = PayOffer (UUID .randomUUID(), randomKey(), null , 5500 .msat, offer, 20 .seconds)
75
85
val (_, invoiceRequests) = bobOfferManager.requestInvoice(payOffer)
76
86
assertTrue(invoiceRequests.size == 1 )
77
87
val (messageForAlice, nextNodeAlice) = trampolineRelay(invoiceRequests.first(), aliceTrampolineKey)
78
88
assertEquals(Either .Right (EncodedNodeId .WithPublicKey .Wallet (TestConstants .Alice .nodeParams.nodeId)), nextNodeAlice)
79
89
// Alice sends an invoice back to Bob.
80
- val invoiceResponse = aliceOfferManager.receiveMessage(messageForAlice, listOf (), 0 )
90
+ val invoiceResponse = aliceOfferManager.receiveMessage(messageForAlice, listOf (), currentBlockHeight )
81
91
assertIs<OnionMessageAction .SendMessage >(invoiceResponse)
82
92
val (messageForBob, nextNodeBob) = trampolineRelay(invoiceResponse.message, aliceTrampolineKey)
83
93
assertEquals(Either .Right (EncodedNodeId .WithPublicKey .Wallet (TestConstants .Bob .nodeParams.nodeId)), nextNodeBob)
84
- val payInvoice = bobOfferManager.receiveMessage(messageForBob, listOf (), 0 )
94
+ val payInvoice = bobOfferManager.receiveMessage(messageForBob, listOf (), currentBlockHeight )
85
95
assertIs<OnionMessageAction .PayInvoice >(payInvoice)
86
96
assertEquals(OfferInvoiceReceived (payOffer, payInvoice.invoice), bobOfferManager.eventsFlow.first())
87
97
assertEquals(payOffer, payInvoice.payOffer)
@@ -91,6 +101,10 @@ class OfferManagerTestsCommon : LightningTestSuite() {
91
101
assertEquals(aliceOfferManager.nodeParams.expiryDeltaBlocks + aliceOfferManager.nodeParams.minFinalCltvExpiryDelta, path.paymentInfo.cltvExpiryDelta)
92
102
assertEquals(TestConstants .Alice .nodeParams.htlcMinimum, path.paymentInfo.minHtlc)
93
103
assertEquals(payOffer.amount * 2 , path.paymentInfo.maxHtlc)
104
+ // The blinded path expires long after the invoice expiry to allow senders to add their own expiry delta.
105
+ val (alicePayload, _) = RouteBlinding .decryptPayload(aliceTrampolineKey, path.route.route.blindingKey, path.route.route.encryptedPayloads.first()).right!!
106
+ val paymentConstraints = RouteBlindingEncryptedData .read(alicePayload.toByteArray()).right!! .paymentConstraints!!
107
+ assertTrue(paymentConstraints.maxCltvExpiry > CltvExpiryDelta (720 ).toCltvExpiry(currentBlockHeight.toLong()))
94
108
}
95
109
96
110
@Test
@@ -271,17 +285,8 @@ class OfferManagerTestsCommon : LightningTestSuite() {
271
285
assertEquals(OfferInvoiceReceived (payOffer, payInvoice.invoice), bobOfferManager.eventsFlow.first())
272
286
assertEquals(payOffer, payInvoice.payOffer)
273
287
274
- val blindedRoute = payInvoice.invoice.blindedPaths.first().route.route
275
- val (firstPayload, secondBlinding) = RouteBlinding .decryptPayload(aliceTrampolineKey, blindedRoute.blindingKey, blindedRoute.encryptedPayloads.first()).right!!
276
- var blinding = secondBlinding
277
- var lastPayload = firstPayload
278
- for (encryptedPayload in blindedRoute.encryptedPayloads.drop(1 )) {
279
- val (payload, nextBlinding) = RouteBlinding .decryptPayload(TestConstants .Alice .nodeParams.nodePrivateKey, blinding, encryptedPayload).right!!
280
- blinding = nextBlinding
281
- lastPayload = payload
282
- }
283
- val pathId = RouteBlindingEncryptedData .read(lastPayload.toByteArray()).right!! .pathId!!
284
- val metadata = OfferPaymentMetadata .fromPathId(TestConstants .Alice .nodeParams.nodeId, pathId) as OfferPaymentMetadata .V1
288
+ // The payer note is correctly included in the payment metadata.
289
+ val metadata = decryptPathId(payInvoice.invoice, aliceTrampolineKey)
285
290
assertEquals(payerNote, metadata.payerNote)
286
291
}
287
292
@@ -309,18 +314,10 @@ class OfferManagerTestsCommon : LightningTestSuite() {
309
314
assertEquals(OfferInvoiceReceived (payOffer, payInvoice.invoice), bobOfferManager.eventsFlow.first())
310
315
assertEquals(payOffer, payInvoice.payOffer)
311
316
312
- val blindedRoute = payInvoice.invoice.blindedPaths.first().route.route
313
- val (firstPayload, secondBlinding) = RouteBlinding .decryptPayload(aliceTrampolineKey, blindedRoute.blindingKey, blindedRoute.encryptedPayloads.first()).right!!
314
- var blinding = secondBlinding
315
- var lastPayload = firstPayload
316
- for (encryptedPayload in blindedRoute.encryptedPayloads.drop(1 )) {
317
- val (payload, nextBlinding) = RouteBlinding .decryptPayload(TestConstants .Alice .nodeParams.nodePrivateKey, blinding, encryptedPayload).right!!
318
- blinding = nextBlinding
319
- lastPayload = payload
320
- }
321
- val pathId = RouteBlindingEncryptedData .read(lastPayload.toByteArray()).right!! .pathId!!
322
- val metadata = OfferPaymentMetadata .fromPathId(TestConstants .Alice .nodeParams.nodeId, pathId) as OfferPaymentMetadata .V1
317
+ // The payer note is truncated in the payment metadata.
318
+ val metadata = decryptPathId(payInvoice.invoice, aliceTrampolineKey)
323
319
assertEquals(64 , metadata.payerNote!! .length)
324
320
assertEquals(payerNote.take(63 ), metadata.payerNote!! .take(63 ))
325
321
}
322
+
326
323
}
0 commit comments