mirror of
https://github.com/ACINQ/eclair.git
synced 2025-03-13 19:37:35 +01:00
Accept to pay amountless trampoline invoices (phoenix special)
This commit is contained in:
parent
a6d23d4f8a
commit
e543dff0a2
1 changed files with 21 additions and 21 deletions
|
@ -68,28 +68,28 @@ class PaymentInitiator(nodeParams: NodeParams, router: ActorRef, relayer: ActorR
|
|||
val paymentId = UUID.randomUUID()
|
||||
sender ! paymentId
|
||||
if (!r.paymentRequest.features.allowTrampoline && r.paymentRequest.amount.isEmpty) {
|
||||
sender ! PaymentFailed(paymentId, r.paymentRequest.paymentHash, LocalFailure(new IllegalArgumentException("cannot pay a 0-value invoice via trampoline-to-legacy (trampoline may steal funds)")) :: Nil)
|
||||
} else {
|
||||
val paymentCfg = SendPaymentConfig(paymentId, paymentId, None, r.paymentRequest.paymentHash, r.trampolineNodeId, Upstream.Local(paymentId), Some(r.paymentRequest), storeInDb = true, publishEvent = true, Some(r))
|
||||
val finalPayload = if (r.paymentRequest.features.allowMultiPart) {
|
||||
Onion.createMultiPartPayload(r.finalAmount, r.finalAmount, r.finalExpiry(nodeParams.currentBlockHeight), r.paymentRequest.paymentSecret.get)
|
||||
} else {
|
||||
Onion.createSinglePartPayload(r.finalAmount, r.finalExpiry(nodeParams.currentBlockHeight), r.paymentRequest.paymentSecret)
|
||||
}
|
||||
val trampolineRoute = Seq(
|
||||
NodeHop(nodeParams.nodeId, r.trampolineNodeId, nodeParams.expiryDeltaBlocks, 0 msat),
|
||||
NodeHop(r.trampolineNodeId, r.paymentRequest.nodeId, r.trampolineExpiryDelta, r.trampolineFees) // for now we only use a single trampoline hop
|
||||
)
|
||||
// We assume that the trampoline node supports multi-part payments (it should).
|
||||
val (trampolineAmount, trampolineExpiry, trampolineOnion) = if (r.paymentRequest.features.allowTrampoline) {
|
||||
OutgoingPacket.buildPacket(Sphinx.TrampolinePacket)(r.paymentRequest.paymentHash, trampolineRoute, finalPayload)
|
||||
} else {
|
||||
OutgoingPacket.buildTrampolineToLegacyPacket(r.paymentRequest, trampolineRoute, finalPayload)
|
||||
}
|
||||
// We generate a random secret for this payment to avoid leaking the invoice secret to the first trampoline node.
|
||||
val trampolineSecret = randomBytes32
|
||||
spawnMultiPartPaymentFsm(paymentCfg) forward SendMultiPartPayment(r.paymentRequest.paymentHash, trampolineSecret, r.trampolineNodeId, trampolineAmount, trampolineExpiry, 1, r.paymentRequest.routingInfo, r.routeParams, Seq(OnionTlv.TrampolineOnion(trampolineOnion.packet)))
|
||||
// Phoenix special case: we allow paying an amountless payment request over trampoline. It's ok because user has been warned in Phoenix.
|
||||
log.info("trying to pay an amountless invoice over trampoline")
|
||||
}
|
||||
val paymentCfg = SendPaymentConfig(paymentId, paymentId, None, r.paymentRequest.paymentHash, r.trampolineNodeId, Upstream.Local(paymentId), Some(r.paymentRequest), storeInDb = true, publishEvent = true, Some(r))
|
||||
val finalPayload = if (r.paymentRequest.features.allowMultiPart) {
|
||||
Onion.createMultiPartPayload(r.finalAmount, r.finalAmount, r.finalExpiry(nodeParams.currentBlockHeight), r.paymentRequest.paymentSecret.get)
|
||||
} else {
|
||||
Onion.createSinglePartPayload(r.finalAmount, r.finalExpiry(nodeParams.currentBlockHeight), r.paymentRequest.paymentSecret)
|
||||
}
|
||||
val trampolineRoute = Seq(
|
||||
NodeHop(nodeParams.nodeId, r.trampolineNodeId, nodeParams.expiryDeltaBlocks, 0 msat),
|
||||
NodeHop(r.trampolineNodeId, r.paymentRequest.nodeId, r.trampolineExpiryDelta, r.trampolineFees) // for now we only use a single trampoline hop
|
||||
)
|
||||
// We assume that the trampoline node supports multi-part payments (it should).
|
||||
val (trampolineAmount, trampolineExpiry, trampolineOnion) = if (r.paymentRequest.features.allowTrampoline) {
|
||||
OutgoingPacket.buildPacket(Sphinx.TrampolinePacket)(r.paymentRequest.paymentHash, trampolineRoute, finalPayload)
|
||||
} else {
|
||||
OutgoingPacket.buildTrampolineToLegacyPacket(r.paymentRequest, trampolineRoute, finalPayload)
|
||||
}
|
||||
// We generate a random secret for this payment to avoid leaking the invoice secret to the first trampoline node.
|
||||
val trampolineSecret = randomBytes32
|
||||
spawnMultiPartPaymentFsm(paymentCfg) forward SendMultiPartPayment(r.paymentRequest.paymentHash, trampolineSecret, r.trampolineNodeId, trampolineAmount, trampolineExpiry, 1, r.paymentRequest.routingInfo, r.routeParams, Seq(OnionTlv.TrampolineOnion(trampolineOnion.packet)))
|
||||
}
|
||||
|
||||
def spawnPaymentFsm(paymentCfg: SendPaymentConfig): ActorRef = context.actorOf(PaymentLifecycle.props(nodeParams, paymentCfg, router, register))
|
||||
|
|
Loading…
Add table
Reference in a new issue