@@ -419,6 +419,39 @@ func (s *InterceptorService) AssociateInvoice(id AccountID,
419419 return s .store .UpdateAccount (account )
420420}
421421
422+ // AssociatePayment associates a payment (hash) with the given account,
423+ // ensuring that the payment will be tracked for a user when LiT is
424+ // restarted.
425+ func (s * InterceptorService ) AssociatePayment (id AccountID ,
426+ paymentHash lntypes.Hash , fullAmt lnwire.MilliSatoshi ) error {
427+
428+ s .Lock ()
429+ defer s .Unlock ()
430+
431+ account , err := s .store .Account (id )
432+ if err != nil {
433+ return err
434+ }
435+
436+ // If the payment is already associated with the account, we don't need
437+ // to associate it again.
438+ _ , ok := account .Payments [paymentHash ]
439+ if ok {
440+ return nil
441+ }
442+
443+ // Associate the payment with the account and store it.
444+ account .Payments [paymentHash ] = & PaymentEntry {
445+ Status : lnrpc .Payment_UNKNOWN ,
446+ FullAmount : fullAmt ,
447+ }
448+ if err := s .store .UpdateAccount (account ); err != nil {
449+ return fmt .Errorf ("error updating account: %w" , err )
450+ }
451+
452+ return nil
453+ }
454+
422455// invoiceUpdate credits the account an invoice was registered with, in case the
423456// invoice was settled.
424457//
@@ -531,13 +564,33 @@ func (s *InterceptorService) TrackPayment(id AccountID, hash lntypes.Hash,
531564 return nil
532565 }
533566
534- // Okay, we haven't tracked this payment before. So let's now associate
535- // the account with it.
536567 account .Payments [hash ] = & PaymentEntry {
537568 Status : lnrpc .Payment_UNKNOWN ,
538569 FullAmount : fullAmt ,
539570 }
571+
540572 if err := s .store .UpdateAccount (account ); err != nil {
573+ if ! ok {
574+ // In the rare case that the payment isn't associated
575+ // with an account yet, and we fail to update the
576+ // account we will not be tracking the payment, even if
577+ // track the service is restarted. Therefore the node
578+ // runner needs to manually check if the payment was
579+ // made and debit the account if that's the case.
580+ errStr := "critical error: failed to store the " +
581+ "payment with hash %v for user with account " +
582+ "id %v. Manual intervention required! " +
583+ "Verify if the payment was executed, and " +
584+ "manually update the user account balance by " +
585+ "subtracting the payment amount if it was"
586+
587+ mainChanErr := s .disableAndErrorfUnsafe (
588+ errStr , hash , id ,
589+ )
590+
591+ s .mainErrCallback (mainChanErr )
592+ }
593+
541594 return fmt .Errorf ("error updating account: %w" , err )
542595 }
543596
0 commit comments