@@ -128,7 +128,7 @@ const (
128128// results is sent back. then process its result here. When there's no need to
129129// wait for results, the method will exit with `stepExit` such that the payment
130130// lifecycle loop will terminate.
131- func (p * paymentLifecycle ) decideNextStep (
131+ func (p * paymentLifecycle ) decideNextStep (ctx context. Context ,
132132 payment paymentsdb.DBMPPayment ) (stateStep , error ) {
133133
134134 // Check whether we could make new HTLC attempts.
@@ -168,7 +168,7 @@ func (p *paymentLifecycle) decideNextStep(
168168 // stepSkip and move to the next lifecycle iteration, which will
169169 // refresh the payment and wait for the next attempt result, if
170170 // any.
171- _ , err := p .handleAttemptResult (r .attempt , r .result )
171+ _ , err := p .handleAttemptResult (ctx , r .attempt , r .result )
172172
173173 // We would only get a DB-related error here, which will cause
174174 // us to abort the payment flow.
@@ -192,6 +192,13 @@ func (p *paymentLifecycle) resumePayment(ctx context.Context) ([32]byte,
192192
193193 // We need to make sure we can still do db operations after the context
194194 // is cancelled.
195+ //
196+ // TODO(ziggie): This is a workaround to avoid a greater refactor of the
197+ // payment lifecycle. We can currently not rely on the parent context
198+ // because this method is also collecting the results of inflight HTLCs
199+ // after the context is cancelled. So we need to make sure we only use
200+ // the current context to stop creating new attempts but use this
201+ // cleanupCtx to do all the db operations.
195202 cleanupCtx := context .WithoutCancel (ctx )
196203
197204 // When the payment lifecycle loop exits, we make sure to signal any
@@ -202,7 +209,7 @@ func (p *paymentLifecycle) resumePayment(ctx context.Context) ([32]byte,
202209 // If we had any existing attempts outstanding, we'll start by spinning
203210 // up goroutines that'll collect their results and deliver them to the
204211 // lifecycle loop below.
205- payment , err := p .reloadInflightAttempts ()
212+ payment , err := p .reloadInflightAttempts (ctx )
206213 if err != nil {
207214 return [32 ]byte {}, nil , err
208215 }
@@ -243,7 +250,7 @@ lifecycle:
243250 }
244251
245252 // We update the payment state on every iteration.
246- currentPayment , ps , err := p .reloadPayment ()
253+ currentPayment , ps , err := p .reloadPayment (cleanupCtx )
247254 if err != nil {
248255 return exitWithErr (err )
249256 }
@@ -264,7 +271,7 @@ lifecycle:
264271 //
265272
266273 // Now decide the next step of the current lifecycle.
267- step , err := p .decideNextStep (payment )
274+ step , err := p .decideNextStep (cleanupCtx , payment )
268275 if err != nil {
269276 return exitWithErr (err )
270277 }
@@ -288,7 +295,7 @@ lifecycle:
288295 }
289296
290297 // Now request a route to be used to create our HTLC attempt.
291- rt , err := p .requestRoute (ps )
298+ rt , err := p .requestRoute (cleanupCtx , ps )
292299 if err != nil {
293300 return exitWithErr (err )
294301 }
@@ -307,13 +314,15 @@ lifecycle:
307314 log .Tracef ("Found route: %s" , lnutils .SpewLogClosure (rt .Hops ))
308315
309316 // We found a route to try, create a new HTLC attempt to try.
310- attempt , err := p .registerAttempt (rt , ps .RemainingAmt )
317+ attempt , err := p .registerAttempt (
318+ cleanupCtx , rt , ps .RemainingAmt ,
319+ )
311320 if err != nil {
312321 return exitWithErr (err )
313322 }
314323
315324 // Once the attempt is created, send it to the htlcswitch.
316- result , err := p .sendAttempt (attempt )
325+ result , err := p .sendAttempt (cleanupCtx , attempt )
317326 if err != nil {
318327 return exitWithErr (err )
319328 }
@@ -399,11 +408,9 @@ func (p *paymentLifecycle) checkContext(ctx context.Context) error {
399408
400409// requestRoute is responsible for finding a route to be used to create an HTLC
401410// attempt.
402- func (p * paymentLifecycle ) requestRoute (
411+ func (p * paymentLifecycle ) requestRoute (ctx context. Context ,
403412 ps * paymentsdb.MPPaymentState ) (* route.Route , error ) {
404413
405- ctx := context .TODO ()
406-
407414 remainingFees := p .calcFeeBudget (ps .FeesPaid )
408415
409416 // Query our payment session to construct a route.
@@ -598,11 +605,9 @@ func (p *paymentLifecycle) collectResult(
598605// registerAttempt is responsible for creating and saving an HTLC attempt in db
599606// by using the route info provided. The `remainingAmt` is used to decide
600607// whether this is the last attempt.
601- func (p * paymentLifecycle ) registerAttempt (rt * route.Route ,
608+ func (p * paymentLifecycle ) registerAttempt (ctx context. Context , rt * route.Route ,
602609 remainingAmt lnwire.MilliSatoshi ) (* paymentsdb.HTLCAttempt , error ) {
603610
604- ctx := context .TODO ()
605-
606611 // If this route will consume the last remaining amount to send
607612 // to the receiver, this will be our last shard (for now).
608613 isLastAttempt := rt .ReceiverAmt () == remainingAmt
@@ -676,7 +681,7 @@ func (p *paymentLifecycle) createNewPaymentAttempt(rt *route.Route,
676681// sendAttempt attempts to send the current attempt to the switch to complete
677682// the payment. If this attempt fails, then we'll continue on to the next
678683// available route.
679- func (p * paymentLifecycle ) sendAttempt (
684+ func (p * paymentLifecycle ) sendAttempt (ctx context. Context ,
680685 attempt * paymentsdb.HTLCAttempt ) (* attemptResult , error ) {
681686
682687 log .Debugf ("Sending HTLC attempt(id=%v, total_amt=%v, first_hop_amt=%d" +
@@ -708,7 +713,7 @@ func (p *paymentLifecycle) sendAttempt(
708713 "payment=%v, err:%v" , attempt .AttemptID ,
709714 p .identifier , err )
710715
711- return p .failAttempt (attempt .AttemptID , err )
716+ return p .failAttempt (ctx , attempt .AttemptID , err )
712717 }
713718
714719 htlcAdd .OnionBlob = onionBlob
@@ -722,7 +727,7 @@ func (p *paymentLifecycle) sendAttempt(
722727 log .Errorf ("Failed sending attempt %d for payment %v to " +
723728 "switch: %v" , attempt .AttemptID , p .identifier , err )
724729
725- return p .handleSwitchErr (attempt , err )
730+ return p .handleSwitchErr (ctx , attempt , err )
726731 }
727732
728733 log .Debugf ("Attempt %v for payment %v successfully sent to switch, " +
@@ -813,12 +818,10 @@ func (p *paymentLifecycle) amendFirstHopData(rt *route.Route) error {
813818
814819// failAttemptAndPayment fails both the payment and its attempt via the
815820// router's control tower, which marks the payment as failed in db.
816- func (p * paymentLifecycle ) failPaymentAndAttempt (
821+ func (p * paymentLifecycle ) failPaymentAndAttempt (ctx context. Context ,
817822 attemptID uint64 , reason * paymentsdb.FailureReason ,
818823 sendErr error ) (* attemptResult , error ) {
819824
820- ctx := context .TODO ()
821-
822825 log .Errorf ("Payment %v failed: final_outcome=%v, raw_err=%v" ,
823826 p .identifier , * reason , sendErr )
824827
@@ -836,7 +839,7 @@ func (p *paymentLifecycle) failPaymentAndAttempt(
836839 }
837840
838841 // Fail the attempt.
839- return p .failAttempt (attemptID , sendErr )
842+ return p .failAttempt (ctx , attemptID , sendErr )
840843}
841844
842845// handleSwitchErr inspects the given error from the Switch and determines
@@ -847,7 +850,8 @@ func (p *paymentLifecycle) failPaymentAndAttempt(
847850// the error type, the error is either the final outcome of the payment or we
848851// need to continue with an alternative route. A final outcome is indicated by
849852// a non-nil reason value.
850- func (p * paymentLifecycle ) handleSwitchErr (attempt * paymentsdb.HTLCAttempt ,
853+ func (p * paymentLifecycle ) handleSwitchErr (ctx context.Context ,
854+ attempt * paymentsdb.HTLCAttempt ,
851855 sendErr error ) (* attemptResult , error ) {
852856
853857 internalErrorReason := paymentsdb .FailureReasonError
@@ -874,11 +878,11 @@ func (p *paymentLifecycle) handleSwitchErr(attempt *paymentsdb.HTLCAttempt,
874878 // Fail the attempt only if there's no reason.
875879 if reason == nil {
876880 // Fail the attempt.
877- return p .failAttempt (attemptID , sendErr )
881+ return p .failAttempt (ctx , attemptID , sendErr )
878882 }
879883
880884 // Otherwise fail both the payment and the attempt.
881- return p .failPaymentAndAttempt (attemptID , reason , sendErr )
885+ return p .failPaymentAndAttempt (ctx , attemptID , reason , sendErr )
882886 }
883887
884888 // If this attempt ID is unknown to the Switch, it means it was never
@@ -889,7 +893,7 @@ func (p *paymentLifecycle) handleSwitchErr(attempt *paymentsdb.HTLCAttempt,
889893 log .Warnf ("Failing attempt=%v for payment=%v as it's not " +
890894 "found in the Switch" , attempt .AttemptID , p .identifier )
891895
892- return p .failAttempt (attemptID , sendErr )
896+ return p .failAttempt (ctx , attemptID , sendErr )
893897 }
894898
895899 if errors .Is (sendErr , htlcswitch .ErrUnreadableFailureMessage ) {
@@ -911,7 +915,7 @@ func (p *paymentLifecycle) handleSwitchErr(attempt *paymentsdb.HTLCAttempt,
911915 ok := errors .As (sendErr , & rtErr )
912916 if ! ok {
913917 return p .failPaymentAndAttempt (
914- attemptID , & internalErrorReason , sendErr ,
918+ ctx , attemptID , & internalErrorReason , sendErr ,
915919 )
916920 }
917921
@@ -937,7 +941,7 @@ func (p *paymentLifecycle) handleSwitchErr(attempt *paymentsdb.HTLCAttempt,
937941 )
938942 if err != nil {
939943 return p .failPaymentAndAttempt (
940- attemptID , & internalErrorReason , sendErr ,
944+ ctx , attemptID , & internalErrorReason , sendErr ,
941945 )
942946 }
943947
@@ -1021,11 +1025,9 @@ func (p *paymentLifecycle) handleFailureMessage(rt *route.Route,
10211025}
10221026
10231027// failAttempt calls control tower to fail the current payment attempt.
1024- func (p * paymentLifecycle ) failAttempt (attemptID uint64 ,
1028+ func (p * paymentLifecycle ) failAttempt (ctx context. Context , attemptID uint64 ,
10251029 sendError error ) (* attemptResult , error ) {
10261030
1027- ctx := context .TODO ()
1028-
10291031 log .Warnf ("Attempt %v for payment %v failed: %v" , attemptID ,
10301032 p .identifier , sendError )
10311033
@@ -1136,10 +1138,8 @@ func (p *paymentLifecycle) patchLegacyPaymentHash(
11361138// reloadInflightAttempts is called when the payment lifecycle is resumed after
11371139// a restart. It reloads all inflight attempts from the control tower and
11381140// collects the results of the attempts that have been sent before.
1139- func (p * paymentLifecycle ) reloadInflightAttempts () (paymentsdb.DBMPPayment ,
1140- error ) {
1141-
1142- ctx := context .TODO ()
1141+ func (p * paymentLifecycle ) reloadInflightAttempts (
1142+ ctx context.Context ) (paymentsdb.DBMPPayment , error ) {
11431143
11441144 payment , err := p .router .cfg .Control .FetchPayment (ctx , p .identifier )
11451145 if err != nil {
@@ -1163,11 +1163,10 @@ func (p *paymentLifecycle) reloadInflightAttempts() (paymentsdb.DBMPPayment,
11631163}
11641164
11651165// reloadPayment returns the latest payment found in the db (control tower).
1166- func (p * paymentLifecycle ) reloadPayment () (paymentsdb.DBMPPayment ,
1166+ func (p * paymentLifecycle ) reloadPayment (
1167+ ctx context.Context ) (paymentsdb.DBMPPayment ,
11671168 * paymentsdb.MPPaymentState , error ) {
11681169
1169- ctx := context .TODO ()
1170-
11711170 // Read the db to get the latest state of the payment.
11721171 payment , err := p .router .cfg .Control .FetchPayment (ctx , p .identifier )
11731172 if err != nil {
@@ -1186,15 +1185,14 @@ func (p *paymentLifecycle) reloadPayment() (paymentsdb.DBMPPayment,
11861185
11871186// handleAttemptResult processes the result of an HTLC attempt returned from
11881187// the htlcswitch.
1189- func (p * paymentLifecycle ) handleAttemptResult (attempt * paymentsdb.HTLCAttempt ,
1188+ func (p * paymentLifecycle ) handleAttemptResult (ctx context.Context ,
1189+ attempt * paymentsdb.HTLCAttempt ,
11901190 result * htlcswitch.PaymentResult ) (* attemptResult , error ) {
11911191
1192- ctx := context .TODO ()
1193-
11941192 // If the result has an error, we need to further process it by failing
11951193 // the attempt and maybe fail the payment.
11961194 if result .Error != nil {
1197- return p .handleSwitchErr (attempt , result .Error )
1195+ return p .handleSwitchErr (ctx , attempt , result .Error )
11981196 }
11991197
12001198 // We got an attempt settled result back from the switch.
@@ -1237,13 +1235,13 @@ func (p *paymentLifecycle) handleAttemptResult(attempt *paymentsdb.HTLCAttempt,
12371235// available from the Switch, then records the attempt outcome with the control
12381236// tower. An attemptResult is returned, indicating the final outcome of this
12391237// HTLC attempt.
1240- func (p * paymentLifecycle ) collectAndHandleResult (
1238+ func (p * paymentLifecycle ) collectAndHandleResult (ctx context. Context ,
12411239 attempt * paymentsdb.HTLCAttempt ) (* attemptResult , error ) {
12421240
12431241 result , err := p .collectResult (attempt )
12441242 if err != nil {
12451243 return nil , err
12461244 }
12471245
1248- return p .handleAttemptResult (attempt , result )
1246+ return p .handleAttemptResult (ctx , attempt , result )
12491247}
0 commit comments