mirror of
https://github.com/ACINQ/eclair.git
synced 2025-02-24 06:47:46 +01:00
PaymentLifecycle should tell the router to ignore route prefix (#1217)
When paying a multi-part payment, we tell the PaymentLifecycle to use a route prefix that contains the first hop (for example a -> b via channel 1). We need to also tell the router to ignore the nodes that are in the route prefix, otherwise when retrying it may try some completely dumb routes that have no chance of succeeding.
This commit is contained in:
parent
f45dc1c0fd
commit
c76cc5bfe6
2 changed files with 8 additions and 6 deletions
|
@ -59,11 +59,13 @@ class PaymentLifecycle(nodeParams: NodeParams, cfg: SendPaymentConfig, router: A
|
|||
|
||||
case Event(c: SendPayment, WaitingForRequest) =>
|
||||
log.debug("sending {} to {}{}", c.finalPayload.amount, c.targetNodeId, c.routePrefix.mkString(" with route prefix ", "->", ""))
|
||||
// We don't want the router to try cycling back to nodes that are at the beginning of the route.
|
||||
val ignoredNodes = c.routePrefix.map(_.nodeId).toSet
|
||||
if (c.routePrefix.lastOption.exists(_.nextNodeId == c.targetNodeId)) {
|
||||
// If the sender already provided a route to the target, no need to involve the router.
|
||||
self ! RouteResponse(Nil, Set.empty, Set.empty, allowEmpty = true)
|
||||
self ! RouteResponse(Nil, ignoredNodes, Set.empty, allowEmpty = true)
|
||||
} else {
|
||||
router ! RouteRequest(c.getRouteRequestStart(nodeParams), c.targetNodeId, c.finalPayload.amount, c.assistedRoutes, routeParams = c.routeParams)
|
||||
router ! RouteRequest(c.getRouteRequestStart(nodeParams), c.targetNodeId, c.finalPayload.amount, c.assistedRoutes, routeParams = c.routeParams, ignoreNodes = ignoredNodes)
|
||||
}
|
||||
if (cfg.storeInDb) {
|
||||
paymentsDb.addOutgoingPayment(OutgoingPayment(id, cfg.parentId, cfg.externalId, cfg.paymentHash, c.finalPayload.amount, cfg.targetNodeId, Platform.currentTime, cfg.paymentRequest, OutgoingPaymentStatus.Pending))
|
||||
|
|
|
@ -120,7 +120,7 @@ class PaymentLifecycleSpec extends BaseRouterSpec {
|
|||
|
||||
val request = SendPayment(defaultPaymentHash, d, FinalLegacyPayload(defaultAmountMsat, defaultExpiry), 3, routePrefix = Seq(ChannelHop(a, b, channelUpdate_ab), ChannelHop(b, c, channelUpdate_bc)))
|
||||
sender.send(paymentFSM, request)
|
||||
routerForwarder.expectMsg(RouteRequest(c, d, defaultAmountMsat))
|
||||
routerForwarder.expectMsg(RouteRequest(c, d, defaultAmountMsat, ignoreNodes = Set(a, b)))
|
||||
val Transition(_, WAITING_FOR_REQUEST, WAITING_FOR_ROUTE) = monitor.expectMsgClass(classOf[Transition[_]])
|
||||
awaitCond(nodeParams.db.payments.getOutgoingPayment(id).exists(_.status == OutgoingPaymentStatus.Pending))
|
||||
|
||||
|
@ -146,15 +146,15 @@ class PaymentLifecycleSpec extends BaseRouterSpec {
|
|||
|
||||
val request = SendPayment(defaultPaymentHash, d, FinalLegacyPayload(defaultAmountMsat, defaultExpiry), 3, routePrefix = Seq(ChannelHop(a, b, channelUpdate_ab), ChannelHop(b, c, channelUpdate_bc)))
|
||||
sender.send(paymentFSM, request)
|
||||
routerForwarder.expectMsg(RouteRequest(c, d, defaultAmountMsat))
|
||||
routerForwarder.expectMsg(RouteRequest(c, d, defaultAmountMsat, ignoreNodes = Set(a, b)))
|
||||
val Transition(_, WAITING_FOR_REQUEST, WAITING_FOR_ROUTE) = monitor.expectMsgClass(classOf[Transition[_]])
|
||||
awaitCond(nodeParams.db.payments.getOutgoingPayment(id).exists(_.status == OutgoingPaymentStatus.Pending))
|
||||
|
||||
routerForwarder.send(paymentFSM, RouteResponse(Seq(ChannelHop(c, d, channelUpdate_cd)), Set.empty, Set.empty))
|
||||
routerForwarder.send(paymentFSM, RouteResponse(Seq(ChannelHop(c, d, channelUpdate_cd)), Set(a, b), Set.empty))
|
||||
val Transition(_, WAITING_FOR_ROUTE, WAITING_FOR_PAYMENT_COMPLETE) = monitor.expectMsgClass(classOf[Transition[_]])
|
||||
|
||||
sender.send(paymentFSM, UpdateFailMalformedHtlc(randomBytes32, 0, randomBytes32, 0))
|
||||
routerForwarder.expectMsg(RouteRequest(c, d, defaultAmountMsat, ignoreChannels = Set(ChannelDesc(channelUpdate_ab.shortChannelId, a, b))))
|
||||
routerForwarder.expectMsg(RouteRequest(c, d, defaultAmountMsat, ignoreNodes = Set(a, b), ignoreChannels = Set(ChannelDesc(channelUpdate_ab.shortChannelId, a, b))))
|
||||
val Transition(_, WAITING_FOR_PAYMENT_COMPLETE, WAITING_FOR_ROUTE) = monitor.expectMsgClass(classOf[Transition[_]])
|
||||
assert(nodeParams.db.payments.getOutgoingPayment(id).exists(_.status == OutgoingPaymentStatus.Pending))
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue