@@ -416,6 +416,40 @@ func (s *InterceptorService) AssociateInvoice(id AccountID,
416
416
return s .store .UpdateAccount (account )
417
417
}
418
418
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
+
419
453
// invoiceUpdate credits the account an invoice was registered with, in case the
420
454
// invoice was settled.
421
455
//
@@ -527,13 +561,33 @@ func (s *InterceptorService) TrackPayment(id AccountID, hash lntypes.Hash,
527
561
return nil
528
562
}
529
563
530
- // Okay, we haven't tracked this payment before. So let's now associate
531
- // the account with it.
532
564
account .Payments [hash ] = & PaymentEntry {
533
565
Status : lnrpc .Payment_UNKNOWN ,
534
566
FullAmount : fullAmt ,
535
567
}
568
+
536
569
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
+
537
591
return fmt .Errorf ("error updating account: %w" , err )
538
592
}
539
593
0 commit comments