Skip to content

Commit f3428cb

Browse files
multi: separate account RPC server init & start
In the upcoming actions migration, we need fetch LNDs macaroons prior to initializing the stores, as the macaroons will be required during the migration. This requires that we setup the connection to LND before we initialize the stores, as we can only fetch the macaroons after the LND connection is established. In preparation of doing so, we cannot reference the stores when initializing/creating the accounts RPC server object, as we do so prior to setting up the LND connection. This commit therefore refactors the accounts RPC server so that we separate the initializing from the starting of the RPC server, and only require the store reference during the actual startup of the RPC server. Note that while this commit adds an `active atomic int32` to the RPC server which must be set toggled before the server will process requests, the RPC proxy and status manager will ensure that no requests get sent to the RPC prior to LiT's subserver being set to running. This is added to ensure that we dont introduce any nil pointer panics in future updates though, as the RPC server would panic in requests were actually processed prior to it having the dependencies injected during the `Start` function. Also note that we still keep the init of the accounts RPC server reference prior to setting up the LND connection, as not doing so would require that we'd refactor the registering of `GrpcSubserver`s in a more complex and in a less elegant way.
1 parent ef87c7a commit f3428cb

File tree

2 files changed

+78
-8
lines changed

2 files changed

+78
-8
lines changed

accounts/rpcserver.go

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package accounts
33
import (
44
"context"
55
"encoding/hex"
6+
"errors"
67
"fmt"
8+
"sync/atomic"
79
"time"
810

911
"github.com/btcsuite/btcd/btcutil"
@@ -16,8 +18,17 @@ import (
1618
"gopkg.in/macaroon.v2"
1719
)
1820

21+
var (
22+
// ErrServerNotActive indicates that the server has started but hasn't
23+
// fully finished the startup process.
24+
ErrServerNotActive = errors.New("accounts server is still in the " +
25+
"process of starting")
26+
)
27+
1928
// RPCServer is the main server that implements the Accounts gRPC service.
2029
type RPCServer struct {
30+
active int32 // atomic
31+
2132
litrpc.UnimplementedAccountsServer
2233

2334
service *InterceptorService
@@ -26,13 +37,31 @@ type RPCServer struct {
2637
}
2738

2839
// NewRPCServer returns a new RPC server for the given service.
29-
func NewRPCServer(service *InterceptorService,
30-
superMacBaker litmac.Baker) *RPCServer {
40+
func NewRPCServer() *RPCServer {
41+
return &RPCServer{}
42+
}
43+
44+
// started returns true if the server has been started, and false otherwise.
45+
// NOTE: This function is safe for concurrent access.
46+
func (s *RPCServer) started() bool {
47+
return atomic.LoadInt32(&s.active) != 0
48+
}
3149

32-
return &RPCServer{
33-
service: service,
34-
superMacBaker: superMacBaker,
50+
// Start adds the necessary dependencies for the RPCServer to be able to process
51+
// requests, and starts the RPCServer.
52+
func (s *RPCServer) Start(service *InterceptorService,
53+
superMacBaker litmac.Baker) error {
54+
55+
if s.started() {
56+
return errors.New("accounts rpc server is already started")
3557
}
58+
59+
s.service = service
60+
s.superMacBaker = superMacBaker
61+
62+
atomic.StoreInt32(&s.active, 1)
63+
64+
return nil
3665
}
3766

3867
// CreateAccount adds an entry to the account database. This entry represents
@@ -50,6 +79,10 @@ func (s *RPCServer) CreateAccount(ctx context.Context,
5079
req *litrpc.CreateAccountRequest) (*litrpc.CreateAccountResponse,
5180
error) {
5281

82+
if !s.started() {
83+
return nil, ErrServerNotActive
84+
}
85+
5386
log.Infof("[createaccount] label=%v, balance=%d, expiration=%d",
5487
req.Label, req.AccountBalance, req.ExpirationDate)
5588

@@ -110,6 +143,10 @@ func (s *RPCServer) CreateAccount(ctx context.Context,
110143
func (s *RPCServer) UpdateAccount(ctx context.Context,
111144
req *litrpc.UpdateAccountRequest) (*litrpc.Account, error) {
112145

146+
if !s.started() {
147+
return nil, ErrServerNotActive
148+
}
149+
113150
log.Infof("[updateaccount] id=%s, label=%v, balance=%d, expiration=%d",
114151
req.Id, req.Label, req.AccountBalance, req.ExpirationDate)
115152

@@ -136,6 +173,10 @@ func (s *RPCServer) CreditAccount(ctx context.Context,
136173
req *litrpc.CreditAccountRequest) (*litrpc.CreditAccountResponse,
137174
error) {
138175

176+
if !s.started() {
177+
return nil, ErrServerNotActive
178+
}
179+
139180
if req.GetAccount() == nil {
140181
return nil, fmt.Errorf("account param must be specified")
141182
}
@@ -174,6 +215,10 @@ func (s *RPCServer) CreditAccount(ctx context.Context,
174215
func (s *RPCServer) DebitAccount(ctx context.Context,
175216
req *litrpc.DebitAccountRequest) (*litrpc.DebitAccountResponse, error) {
176217

218+
if !s.started() {
219+
return nil, ErrServerNotActive
220+
}
221+
177222
if req.GetAccount() == nil {
178223
return nil, fmt.Errorf("account param must be specified")
179224
}
@@ -212,6 +257,10 @@ func (s *RPCServer) DebitAccount(ctx context.Context,
212257
func (s *RPCServer) ListAccounts(ctx context.Context,
213258
_ *litrpc.ListAccountsRequest) (*litrpc.ListAccountsResponse, error) {
214259

260+
if !s.started() {
261+
return nil, ErrServerNotActive
262+
}
263+
215264
log.Info("[listaccounts]")
216265

217266
// Retrieve all accounts from the macaroon account store.
@@ -237,6 +286,10 @@ func (s *RPCServer) ListAccounts(ctx context.Context,
237286
func (s *RPCServer) AccountInfo(ctx context.Context,
238287
req *litrpc.AccountInfoRequest) (*litrpc.Account, error) {
239288

289+
if !s.started() {
290+
return nil, ErrServerNotActive
291+
}
292+
240293
log.Infof("[accountinfo] id=%v, label=%v", req.Id, req.Label)
241294

242295
accountID, err := s.findAccount(ctx, req.Id, req.Label)
@@ -257,6 +310,10 @@ func (s *RPCServer) RemoveAccount(ctx context.Context,
257310
req *litrpc.RemoveAccountRequest) (*litrpc.RemoveAccountResponse,
258311
error) {
259312

313+
if !s.started() {
314+
return nil, ErrServerNotActive
315+
}
316+
260317
log.Infof("[removeaccount] id=%v, label=%v", req.Id, req.Label)
261318

262319
accountID, err := s.findAccount(ctx, req.Id, req.Label)

terminal.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,9 +471,7 @@ func (g *LightningTerminal) start(ctx context.Context) error {
471471
)
472472
}
473473

474-
g.accountRpcServer = accounts.NewRPCServer(
475-
g.accountService, superMacBaker,
476-
)
474+
g.accountRpcServer = accounts.NewRPCServer()
477475

478476
g.ruleMgrs = rules.NewRuleManagerSet()
479477

@@ -1025,6 +1023,21 @@ func (g *LightningTerminal) startInternalSubServers(ctx context.Context,
10251023
}
10261024
g.macaroonServiceStarted = true
10271025

1026+
superMacBaker := func(ctx context.Context, rootKeyID uint64,
1027+
perms []bakery.Op, caveats []macaroon.Caveat) (string, error) {
1028+
1029+
return litmac.BakeSuperMacaroon(
1030+
ctx, g.basicClient, rootKeyID, perms, caveats,
1031+
)
1032+
}
1033+
1034+
log.Infof("Starting LiT accounts server")
1035+
1036+
err = g.accountRpcServer.Start(g.accountService, superMacBaker)
1037+
if err != nil {
1038+
return err
1039+
}
1040+
10281041
if !g.cfg.Autopilot.Disable {
10291042
withLndVersion := func(cfg *autopilotserver.Config) {
10301043
cfg.LndVersion = autopilotserver.Version{

0 commit comments

Comments
 (0)