16
16
17
17
package fr .acinq .eclair .payment .send
18
18
19
+ import java .util .UUID
20
+ import java .util .concurrent .TimeUnit
21
+
19
22
import akka .actor .{ActorRef , FSM , Props , Status }
20
23
import akka .event .Logging .MDC
21
24
import fr .acinq .bitcoin .ByteVector32
22
25
import fr .acinq .bitcoin .Crypto .PublicKey
26
+ import fr .acinq .eclair .channel .{HtlcOverriddenByLocalCommit , HtlcsTimedoutDownstream , HtlcsWillTimeoutUpstream }
23
27
import fr .acinq .eclair .db .{OutgoingPayment , OutgoingPaymentStatus , PaymentType }
24
28
import fr .acinq .eclair .payment .Monitoring .{Metrics , Tags }
25
29
import fr .acinq .eclair .payment .OutgoingPacket .Upstream
@@ -33,9 +37,6 @@ import fr.acinq.eclair.router.Router._
33
37
import fr .acinq .eclair .wire .protocol ._
34
38
import fr .acinq .eclair .{CltvExpiry , FSMDiagnosticActorLogging , Logs , MilliSatoshi , MilliSatoshiLong , NodeParams }
35
39
36
- import java .util .UUID
37
- import java .util .concurrent .TimeUnit
38
-
39
40
/**
40
41
* Created by t-bast on 18/07/2019.
41
42
*/
@@ -112,7 +113,7 @@ class MultiPartPaymentLifecycle(nodeParams: NodeParams, cfg: SendPaymentConfig,
112
113
}
113
114
114
115
case Event (pf : PaymentFailed , d : PaymentProgress ) =>
115
- if (isFinalRecipientFailure (pf, d)) {
116
+ if (abortPayment (pf, d)) {
116
117
gotoAbortedOrStop(PaymentAborted (d.request, d.failures ++ pf.failures, d.pending.keySet - pf.id))
117
118
} else {
118
119
val ignore1 = PaymentFailure .updateIgnored(pf.failures, d.ignore)
@@ -130,7 +131,7 @@ class MultiPartPaymentLifecycle(nodeParams: NodeParams, cfg: SendPaymentConfig,
130
131
131
132
when(PAYMENT_IN_PROGRESS ) {
132
133
case Event (pf : PaymentFailed , d : PaymentProgress ) =>
133
- if (isFinalRecipientFailure (pf, d)) {
134
+ if (abortPayment (pf, d)) {
134
135
gotoAbortedOrStop(PaymentAborted (d.request, d.failures ++ pf.failures, d.pending.keySet - pf.id))
135
136
} else if (d.remainingAttempts == 0 ) {
136
137
val failure = LocalFailure (Nil , PaymentError .RetryExhausted )
@@ -377,10 +378,14 @@ object MultiPartPaymentLifecycle {
377
378
SendPaymentToRoute (replyTo, Right (route), finalPayload)
378
379
}
379
380
380
- /** When we receive an error from the final recipient, we should fail the whole payment, it's useless to retry. */
381
- private def isFinalRecipientFailure (pf : PaymentFailed , d : PaymentProgress ): Boolean = pf.failures.collectFirst {
382
- case f : RemoteFailure if f.e.originNode == d.request.targetNodeId => true
383
- }.getOrElse(false )
381
+ /** When we receive an error from the final recipient or payment gets settled on chain, we should fail the whole payment, it's useless to retry. */
382
+ private def abortPayment (pf : PaymentFailed , d : PaymentProgress ): Boolean = pf.failures.exists {
383
+ case f : RemoteFailure => f.e.originNode == d.request.targetNodeId
384
+ case LocalFailure (_, _ : HtlcOverriddenByLocalCommit ) => true
385
+ case LocalFailure (_, _ : HtlcsWillTimeoutUpstream ) => true
386
+ case LocalFailure (_, _ : HtlcsTimedoutDownstream ) => true
387
+ case _ => false
388
+ }
384
389
385
390
private def remainingToSend (nodeParams : NodeParams , request : SendMultiPartPayment , pending : Iterable [Route ]): (MilliSatoshi , MilliSatoshi ) = {
386
391
val sentAmount = pending.map(_.amount).sum
0 commit comments