Skip to content

Commit 4554b33

Browse files
committed
accounts: implement CreditAccount & DebitAccount
This commit implements the `CreditAccount` and `DebitAccount` endpoints for the accounts subsystem.
1 parent de38373 commit 4554b33

File tree

4 files changed

+141
-0
lines changed

4 files changed

+141
-0
lines changed

accounts/checkers_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,18 @@ type mockService struct {
6363
*requestValuesStore
6464
}
6565

66+
func (m *mockService) CreditAccount(_ context.Context, _ AccountID,
67+
_ lnwire.MilliSatoshi) (*OffChainBalanceAccount, error) {
68+
69+
return nil, nil
70+
}
71+
72+
func (m *mockService) DebitAccount(_ context.Context, _ AccountID,
73+
_ lnwire.MilliSatoshi) (*OffChainBalanceAccount, error) {
74+
75+
return nil, nil
76+
}
77+
6678
func newMockService() *mockService {
6779
return &mockService{
6880
acctBalanceMsat: 0,

accounts/interface.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,16 @@ type Service interface {
331331
PaymentErrored(ctx context.Context, id AccountID,
332332
hash lntypes.Hash) error
333333

334+
// CreditAccount increases the balance of an existing account in the
335+
// database.
336+
CreditAccount(ctx context.Context, accountID AccountID,
337+
amount lnwire.MilliSatoshi) (*OffChainBalanceAccount, error)
338+
339+
// DebitAccount decreases the balance of an existing account in the
340+
// database.
341+
DebitAccount(ctx context.Context, accountID AccountID,
342+
amount lnwire.MilliSatoshi) (*OffChainBalanceAccount, error)
343+
334344
RequestValuesStore
335345
}
336346

accounts/rpcserver.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,75 @@ func (s *RPCServer) UpdateAccount(ctx context.Context,
130130
return marshalAccount(account), nil
131131
}
132132

133+
// CreditAccount increases the balance of an existing account in the account
134+
// database, by the given amount.
135+
func (s *RPCServer) CreditAccount(ctx context.Context,
136+
req *litrpc.CreditAccountRequest) (*litrpc.CreditAccountResponse,
137+
error) {
138+
139+
if req.GetAccount() == nil {
140+
return nil, fmt.Errorf("account param must be specified")
141+
}
142+
143+
log.Infof("[creditaccount] id=%s, label=%v, amount=%d",
144+
req.GetAccount().GetId(), req.GetAccount().GetLabel(),
145+
req.Amount)
146+
147+
amount := lnwire.MilliSatoshi(req.Amount * 1000)
148+
149+
accountID, err := s.findAccount(
150+
ctx, req.GetAccount().GetId(), req.GetAccount().GetLabel(),
151+
)
152+
if err != nil {
153+
return nil, err
154+
}
155+
156+
account, err := s.service.CreditAccount(
157+
ctx, accountID, amount,
158+
)
159+
if err != nil {
160+
return nil, err
161+
}
162+
163+
return &litrpc.CreditAccountResponse{
164+
Account: marshalAccount(account),
165+
}, nil
166+
}
167+
168+
// DebitAccount decreases the balance of an existing account in the account
169+
// database, by the given amount.
170+
func (s *RPCServer) DebitAccount(ctx context.Context,
171+
req *litrpc.DebitAccountRequest) (*litrpc.DebitAccountResponse, error) {
172+
173+
if req.GetAccount() == nil {
174+
return nil, fmt.Errorf("account param must be specified")
175+
}
176+
177+
log.Infof("[debitaccount] id=%s, label=%v, amount=%d",
178+
req.GetAccount().GetId(), req.GetAccount().GetLabel(),
179+
req.Amount)
180+
181+
amount := lnwire.MilliSatoshi(req.Amount * 1000)
182+
183+
accountID, err := s.findAccount(
184+
ctx, req.GetAccount().GetId(), req.GetAccount().GetLabel(),
185+
)
186+
if err != nil {
187+
return nil, err
188+
}
189+
190+
account, err := s.service.DebitAccount(
191+
ctx, accountID, amount,
192+
)
193+
if err != nil {
194+
return nil, err
195+
}
196+
197+
return &litrpc.DebitAccountResponse{
198+
Account: marshalAccount(account),
199+
}, nil
200+
}
201+
133202
// ListAccounts returns all accounts that are currently stored in the account
134203
// database.
135204
func (s *RPCServer) ListAccounts(ctx context.Context,

accounts/service.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,56 @@ func (s *InterceptorService) UpdateAccount(ctx context.Context,
345345
return s.store.Account(ctx, accountID)
346346
}
347347

348+
// CreditAccount increases the balance of an existing account in the database.
349+
func (s *InterceptorService) CreditAccount(ctx context.Context,
350+
accountID AccountID,
351+
amount lnwire.MilliSatoshi) (*OffChainBalanceAccount, error) {
352+
353+
s.Lock()
354+
defer s.Unlock()
355+
356+
// As this function updates account balances, we require that the
357+
// service is running before we execute it.
358+
if !s.isRunningUnsafe() {
359+
// This case can only happen if the service is disabled while
360+
// we're processing a request.
361+
return nil, ErrAccountServiceDisabled
362+
}
363+
364+
// Credit the account in the db.
365+
err := s.store.CreditAccount(ctx, accountID, amount)
366+
if err != nil {
367+
return nil, fmt.Errorf("unable to credit account: %w", err)
368+
}
369+
370+
return s.store.Account(ctx, accountID)
371+
}
372+
373+
// DebitAccount decreases the balance of an existing account in the database.
374+
func (s *InterceptorService) DebitAccount(ctx context.Context,
375+
accountID AccountID,
376+
amount lnwire.MilliSatoshi) (*OffChainBalanceAccount, error) {
377+
378+
s.Lock()
379+
defer s.Unlock()
380+
381+
// As this function updates account balances, we require that the
382+
// service is running before we execute it.
383+
if !s.isRunningUnsafe() {
384+
// This case can only happen if the service is disabled while
385+
// we're processing a request.
386+
return nil, ErrAccountServiceDisabled
387+
}
388+
389+
// Debit the account in the db.
390+
err := s.store.DebitAccount(ctx, accountID, amount)
391+
if err != nil {
392+
return nil, fmt.Errorf("unable to debit account: %w", err)
393+
}
394+
395+
return s.store.Account(ctx, accountID)
396+
}
397+
348398
// Account retrieves an account from the bolt DB and un-marshals it. If the
349399
// account cannot be found, then ErrAccNotFound is returned.
350400
func (s *InterceptorService) Account(ctx context.Context,

0 commit comments

Comments
 (0)