Skip to content

Commit 400a129

Browse files
authored
Merge pull request #981 from ViktorTigerstrom/2025-02-credit-debit-accounts-kvdb-prep
accounts: Credit and debit accounts `kvdb` additions prep
2 parents fff0a73 + 3d67a7e commit 400a129

File tree

4 files changed

+68
-8
lines changed

4 files changed

+68
-8
lines changed

accounts/interface.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,14 @@ type Store interface {
225225
AddAccountInvoice(ctx context.Context, id AccountID,
226226
hash lntypes.Hash) error
227227

228-
// IncreaseAccountBalance increases the balance of the account with the
228+
// CreditAccount increases the balance of the account with the
229229
// given ID by the given amount.
230-
IncreaseAccountBalance(ctx context.Context, id AccountID,
230+
CreditAccount(ctx context.Context, id AccountID,
231+
amount lnwire.MilliSatoshi) error
232+
233+
// DebitAccount decreases the balance of the account with the
234+
// given ID by the given amount.
235+
DebitAccount(ctx context.Context, id AccountID,
231236
amount lnwire.MilliSatoshi) error
232237

233238
// UpsertAccountPayment updates or inserts a payment entry for the given

accounts/service.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ func (s *InterceptorService) invoiceUpdate(ctx context.Context,
563563
// If we get here, the current account has the invoice associated with
564564
// it that was just paid. Credit the amount to the account and update it
565565
// in the DB.
566-
err := s.store.IncreaseAccountBalance(ctx, acctID, invoice.AmountPaid)
566+
err := s.store.CreditAccount(ctx, acctID, invoice.AmountPaid)
567567
if err != nil {
568568
return s.disableAndErrorfUnsafe("error increasing account "+
569569
"balance account: %w", err)

accounts/store_kvdb.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,11 @@ func (s *BoltStore) AddAccountInvoice(_ context.Context, id AccountID,
223223
return s.updateAccount(id, update)
224224
}
225225

226-
// IncreaseAccountBalance increases the balance of the account with the given ID
226+
// CreditAccount increases the balance of the account with the given ID
227227
// by the given amount.
228228
//
229229
// NOTE: This is part of the Store interface.
230-
func (s *BoltStore) IncreaseAccountBalance(_ context.Context, id AccountID,
230+
func (s *BoltStore) CreditAccount(_ context.Context, id AccountID,
231231
amount lnwire.MilliSatoshi) error {
232232

233233
update := func(account *OffChainBalanceAccount) error {
@@ -244,6 +244,33 @@ func (s *BoltStore) IncreaseAccountBalance(_ context.Context, id AccountID,
244244
return s.updateAccount(id, update)
245245
}
246246

247+
// DebitAccount decreases the balance of the account with the given ID
248+
// by the given amount.
249+
//
250+
// NOTE: This is part of the Store interface.
251+
func (s *BoltStore) DebitAccount(_ context.Context, id AccountID,
252+
amount lnwire.MilliSatoshi) error {
253+
254+
if amount > math.MaxInt64 {
255+
return fmt.Errorf("amount %v exceeds the maximum of %v",
256+
amount, int64(math.MaxInt64))
257+
}
258+
259+
update := func(account *OffChainBalanceAccount) error {
260+
if account.CurrentBalance-int64(amount) < 0 {
261+
return fmt.Errorf("cannot debit %v from the account "+
262+
"balance, as the resulting balance would be "+
263+
"below 0", int64(amount/1000))
264+
}
265+
266+
account.CurrentBalance -= int64(amount)
267+
268+
return nil
269+
}
270+
271+
return s.updateAccount(id, update)
272+
}
273+
247274
// UpsertAccountPayment updates or inserts a payment entry for the given
248275
// account. Various functional options can be passed to modify the behavior of
249276
// the method. The returned boolean is true if the payment was already known

accounts/store_test.go

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package accounts
22

33
import (
44
"context"
5+
"github.com/lightningnetwork/lnd/lnwire"
56
"testing"
67
"time"
78

@@ -71,6 +72,14 @@ func TestAccountStore(t *testing.T) {
7172
)
7273
require.NoError(t, err)
7374

75+
// Adjust the account balance by first crediting 10000, and then
76+
// debiting 5000.
77+
err = store.CreditAccount(ctx, acct1.ID, lnwire.MilliSatoshi(10000))
78+
require.NoError(t, err)
79+
80+
err = store.DebitAccount(ctx, acct1.ID, lnwire.MilliSatoshi(5000))
81+
require.NoError(t, err)
82+
7483
// Update the in-memory account so that we can compare it with the
7584
// account we get from the store.
7685
acct1.CurrentBalance = -500
@@ -85,11 +94,30 @@ func TestAccountStore(t *testing.T) {
8594
}
8695
acct1.Invoices[lntypes.Hash{12, 34, 56, 78}] = struct{}{}
8796
acct1.Invoices[lntypes.Hash{34, 56, 78, 90}] = struct{}{}
97+
acct1.CurrentBalance += 10000
98+
acct1.CurrentBalance -= 5000
8899

89100
dbAccount, err = store.Account(ctx, acct1.ID)
90101
require.NoError(t, err)
91102
assertEqualAccounts(t, acct1, dbAccount)
92103

104+
// Test that adjusting the balance to exactly 0 should work, while
105+
// adjusting the balance to below 0 should fail.
106+
err = store.DebitAccount(
107+
ctx, acct1.ID, lnwire.MilliSatoshi(acct1.CurrentBalance),
108+
)
109+
require.NoError(t, err)
110+
111+
acct1.CurrentBalance = 0
112+
113+
dbAccount, err = store.Account(ctx, acct1.ID)
114+
require.NoError(t, err)
115+
assertEqualAccounts(t, acct1, dbAccount)
116+
117+
// Adjusting the value to below 0 should fail.
118+
err = store.DebitAccount(ctx, acct1.ID, lnwire.MilliSatoshi(1))
119+
require.ErrorContains(t, err, "balance would be below 0")
120+
93121
// Sleep just a tiny bit to make sure we are never too quick to measure
94122
// the expiry, even though the time is nanosecond scale and writing to
95123
// the store and reading again should take at least a couple of
@@ -262,12 +290,12 @@ func TestAccountUpdateMethods(t *testing.T) {
262290
assertInvoices(hash1, hash2)
263291
})
264292

265-
t.Run("IncreaseAccountBalance", func(t *testing.T) {
293+
t.Run("CreditAccount", func(t *testing.T) {
266294
store := NewTestDB(t, clock.NewTestClock(time.Now()))
267295

268296
// Increasing the balance of an account that doesn't exist
269297
// should error out.
270-
err := store.IncreaseAccountBalance(ctx, AccountID{}, 100)
298+
err := store.CreditAccount(ctx, AccountID{}, 100)
271299
require.ErrorIs(t, err, ErrAccNotFound)
272300

273301
acct, err := store.NewAccount(ctx, 123, time.Time{}, "foo")
@@ -284,7 +312,7 @@ func TestAccountUpdateMethods(t *testing.T) {
284312

285313
// Increase the balance by 100 and assert that the new balance
286314
// is 223.
287-
err = store.IncreaseAccountBalance(ctx, acct.ID, 100)
315+
err = store.CreditAccount(ctx, acct.ID, 100)
288316
require.NoError(t, err)
289317

290318
assertBalance(223)

0 commit comments

Comments
 (0)