Skip to content

Commit 3d67a7e

Browse files
accounts: implement kvdb DebitAccount
This commit introduces the `DebitAccount` function in the kvdb store, to support decreasing an existing off-chain account’s balance by a specified amount in the database.
1 parent cc003ab commit 3d67a7e

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

accounts/interface.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,11 @@ type Store interface {
230230
CreditAccount(ctx context.Context, id AccountID,
231231
amount lnwire.MilliSatoshi) error
232232

233+
// DebitAccount decreases the balance of the account with the
234+
// given ID by the given amount.
235+
DebitAccount(ctx context.Context, id AccountID,
236+
amount lnwire.MilliSatoshi) error
237+
233238
// UpsertAccountPayment updates or inserts a payment entry for the given
234239
// account. Various functional options can be passed to modify the
235240
// behavior of the method. The returned boolean is true if the payment

accounts/store_kvdb.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,33 @@ func (s *BoltStore) CreditAccount(_ 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: 28 additions & 0 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

0 commit comments

Comments
 (0)