@@ -416,6 +416,40 @@ func (s *InterceptorService) AssociateInvoice(id AccountID,
416416 return s .store .UpdateAccount (account )
417417}
418418
419+ // AssociatePayment associates a payment (hash) with the given account,
420+ // ensuring that the payment will be tracked for a user when LiT is
421+ // restarted.
422+ func (s * InterceptorService ) AssociatePayment (id AccountID ,
423+ paymentHash lntypes.Hash , fullAmt lnwire.MilliSatoshi ) error {
424+
425+ s .Lock ()
426+ defer s .Unlock ()
427+
428+ account , err := s .store .Account (id )
429+ if err != nil {
430+ return err
431+ }
432+
433+ // If the payment is already associated with the account, we don't need
434+ // to associate it again.
435+ _ , ok := account .Payments [paymentHash ]
436+ if ok {
437+ return nil
438+ }
439+
440+ // Associate the payment with the account and store it.
441+ account .Payments [paymentHash ] = & PaymentEntry {
442+ Status : lnrpc .Payment_UNKNOWN ,
443+ FullAmount : fullAmt ,
444+ }
445+
446+ if err := s .store .UpdateAccount (account ); err != nil {
447+ return fmt .Errorf ("error updating account: %w" , err )
448+ }
449+
450+ return nil
451+ }
452+
419453// invoiceUpdate credits the account an invoice was registered with, in case the
420454// invoice was settled.
421455//
@@ -527,13 +561,33 @@ func (s *InterceptorService) TrackPayment(id AccountID, hash lntypes.Hash,
527561 return nil
528562 }
529563
530- // Okay, we haven't tracked this payment before. So let's now associate
531- // the account with it.
532564 account .Payments [hash ] = & PaymentEntry {
533565 Status : lnrpc .Payment_UNKNOWN ,
534566 FullAmount : fullAmt ,
535567 }
568+
536569 if err := s .store .UpdateAccount (account ); err != nil {
570+ if ! ok {
571+ // In the rare case that the payment isn't associated
572+ // with an account yet, and we fail to update the
573+ // account we will not be tracking the payment, even if
574+ // track the service is restarted. Therefore the node
575+ // runner needs to manually check if the payment was
576+ // made and debit the account if that's the case.
577+ errStr := "critical error: failed to store the " +
578+ "payment with hash %v for user with account " +
579+ "id %v. Manual intervention required! " +
580+ "Verify if the payment was executed, and " +
581+ "manually update the user account balance by " +
582+ "subtracting the payment amount if it was"
583+
584+ mainChanErr := s .disableAndErrorfUnsafe (
585+ errStr , hash , id ,
586+ )
587+
588+ s .mainErrCallback (mainChanErr )
589+ }
590+
537591 return fmt .Errorf ("error updating account: %w" , err )
538592 }
539593
0 commit comments