Skip to content

Commit 4d8d4e1

Browse files
committed
accounts: use UpsertAccountPayment in removePayment
Instead of UpdateAccount.
1 parent 7fb7faa commit 4d8d4e1

File tree

5 files changed

+97
-13
lines changed

5 files changed

+97
-13
lines changed

accounts/errors.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ var (
1515
ErrAlreadySucceeded = errors.New("payment has already succeeded")
1616

1717
// ErrPaymentNotAssociated indicate that the payment with the given hash
18-
// has not yet been associated with the account in question.
18+
// has not yet been associated with the account in question. It is also
19+
// returned when the WithErrIfUnknown option is used with
20+
// UpsertAccountPayment if the payment is not yet known.
1921
ErrPaymentNotAssociated = errors.New(
2022
"payment not associated with account",
2123
)

accounts/interface.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ type upsertAcctPaymentOption struct {
345345
errIfAlreadyPending bool
346346
usePendingAmount bool
347347
errIfAlreadySucceeded bool
348+
errIfUnknown bool
348349
}
349350

350351
// newUpsertPaymentOption creates a new upsertAcctPaymentOption with default
@@ -355,6 +356,7 @@ func newUpsertPaymentOption() *upsertAcctPaymentOption {
355356
errIfAlreadyPending: false,
356357
usePendingAmount: false,
357358
errIfAlreadySucceeded: false,
359+
errIfUnknown: false,
358360
}
359361
}
360362

@@ -394,3 +396,12 @@ func WithPendingAmount() UpsertPaymentOption {
394396
o.usePendingAmount = true
395397
}
396398
}
399+
400+
// WithErrIfUnknown is a functional option that can be passed to the
401+
// UpsertAccountPayment method to indicate that the ErrPaymentNotAssociated
402+
// error should be returned if the payment is not associated with the account.
403+
func WithErrIfUnknown() UpsertPaymentOption {
404+
return func(o *upsertAcctPaymentOption) {
405+
o.errIfUnknown = true
406+
}
407+
}

accounts/service.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -840,23 +840,24 @@ func (s *InterceptorService) removePayment(ctx context.Context,
840840
return nil
841841
}
842842

843-
account, err := s.store.Account(ctx, pendingPayment.accountID)
844-
if err != nil {
845-
return err
843+
_, err := s.store.UpsertAccountPayment(
844+
ctx, pendingPayment.accountID, hash, 0, status,
845+
// We don't want the payment to be inserted if it isn't already
846+
// known. So we pass in this option to ensure that the call
847+
// exits early if the payment is unknown.
848+
WithErrIfUnknown(),
849+
// Otherwise, we just want to update the status of the payment
850+
// and use the existing pending amount.
851+
WithPendingAmount(),
852+
)
853+
if err != nil && !errors.Is(err, ErrPaymentNotAssociated) {
854+
return fmt.Errorf("error updating account: %w", err)
846855
}
847856

848857
pendingPayment.cancel()
849858
delete(s.pendingPayments, hash)
850859

851-
// Have we associated the payment with the account already?
852-
_, ok = account.Payments[hash]
853-
if !ok {
854-
return nil
855-
}
856-
857-
// If we did, let's set the status correctly in the DB now.
858-
account.Payments[hash].Status = status
859-
return s.store.UpdateAccount(ctx, account)
860+
return nil
860861
}
861862

862863
// successState returns true if a payment was completed successfully.

accounts/store_kvdb.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,8 @@ func (s *BoltStore) UpsertAccountPayment(_ context.Context, id AccountID,
300300
if opts.usePendingAmount {
301301
fullAmount = entry.FullAmount
302302
}
303+
} else if opts.errIfUnknown {
304+
return ErrPaymentNotAssociated
303305
}
304306

305307
account.Payments[paymentHash] = &PaymentEntry{

accounts/store_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,74 @@ func TestAccountUpdateMethods(t *testing.T) {
430430
// error.
431431
err = store.DeleteAccountPayment(ctx, acct.ID, hash1)
432432
require.ErrorIs(t, err, ErrPaymentNotAssociated)
433+
434+
// Try once more to insert a payment that is currently unknown
435+
// but this time add the WithErrIfUnknown option. This should
436+
// return the ErrPaymentNotAssociated error.
437+
_, err = store.UpsertAccountPayment(
438+
ctx, acct.ID, hash1, 600, lnrpc.Payment_SUCCEEDED,
439+
WithErrIfUnknown(),
440+
)
441+
require.ErrorIs(t, err, ErrPaymentNotAssociated)
442+
443+
// Show that using the two options WithErrIfUnknown and
444+
// WithPendingAmount together will return the
445+
// ErrPaymentNotAssociated and will not successfully update
446+
// the status. We call this for hash1 since it is no longer
447+
// known. We do this to simulate the behaviour of
448+
// removePayment.
449+
_, err = store.UpsertAccountPayment(
450+
ctx, acct.ID, hash1, 0, lnrpc.Payment_SUCCEEDED,
451+
WithErrIfUnknown(),
452+
WithPendingAmount(),
453+
)
454+
require.ErrorIs(t, err, ErrPaymentNotAssociated)
455+
456+
assertBalanceAndPayments(400, AccountPayments{
457+
hash2: &PaymentEntry{
458+
Status: lnrpc.Payment_SUCCEEDED,
459+
FullAmount: 100,
460+
},
461+
})
462+
463+
// Now insert hash 1 again.
464+
_, err = store.UpsertAccountPayment(
465+
ctx, acct.ID, hash1, 600, lnrpc.Payment_IN_FLIGHT,
466+
)
467+
require.NoError(t, err)
468+
469+
assertBalanceAndPayments(400, AccountPayments{
470+
hash1: &PaymentEntry{
471+
Status: lnrpc.Payment_IN_FLIGHT,
472+
FullAmount: 600,
473+
},
474+
hash2: &PaymentEntry{
475+
Status: lnrpc.Payment_SUCCEEDED,
476+
FullAmount: 100,
477+
},
478+
})
479+
480+
// Once again call UpsertAccountPayment with both the
481+
// WithErrIfUnknown and WithPendingAmount options. This time
482+
// it should succeed since the payment is now known and so the
483+
// status should be updated.
484+
_, err = store.UpsertAccountPayment(
485+
ctx, acct.ID, hash1, 0, lnrpc.Payment_SUCCEEDED,
486+
WithErrIfUnknown(),
487+
WithPendingAmount(),
488+
)
489+
require.NoError(t, err)
490+
491+
assertBalanceAndPayments(400, AccountPayments{
492+
hash1: &PaymentEntry{
493+
Status: lnrpc.Payment_SUCCEEDED,
494+
FullAmount: 600,
495+
},
496+
hash2: &PaymentEntry{
497+
Status: lnrpc.Payment_SUCCEEDED,
498+
FullAmount: 100,
499+
},
500+
})
433501
})
434502
}
435503

0 commit comments

Comments
 (0)