Skip to content

Commit 37b24d5

Browse files
ellemoutonpositiveblue
authored andcommitted
multi: split out LND connection from rpcProxy
Remove the responsibility of creating an LND connection from the rpcProxy and instead let the main LightningTerminal struct handle it. All the lnd-connection specific functions are also moved into their own file.
1 parent 116322d commit 37b24d5

File tree

3 files changed

+104
-93
lines changed

3 files changed

+104
-93
lines changed

lnd_connection.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package terminal
2+
3+
import (
4+
"context"
5+
"crypto/tls"
6+
"fmt"
7+
"net"
8+
9+
grpcProxy "github.com/mwitkow/grpc-proxy/proxy"
10+
"google.golang.org/grpc"
11+
"google.golang.org/grpc/backoff"
12+
"google.golang.org/grpc/credentials"
13+
"google.golang.org/grpc/test/bufconn"
14+
)
15+
16+
// connectLND sets up LiT's LND connection.
17+
func connectLND(cfg *Config, bufListener *bufconn.Listener) (*grpc.ClientConn,
18+
error) {
19+
20+
if cfg.lndRemote {
21+
host, _, tlsPath, _, _ := cfg.lndConnectParams()
22+
return dialBackend("lnd", host, tlsPath)
23+
}
24+
25+
// If LND is running in integrated mode, then we use a bufconn to
26+
// connect to lnd in integrated mode.
27+
return dialBufConnBackend(bufListener)
28+
}
29+
30+
// dialBackend connects to a gRPC backend through the given address and uses the
31+
// given TLS certificate to authenticate the connection.
32+
func dialBackend(name, dialAddr, tlsCertPath string) (*grpc.ClientConn, error) {
33+
tlsConfig, err := credentials.NewClientTLSFromFile(tlsCertPath, "")
34+
if err != nil {
35+
return nil, fmt.Errorf("could not read %s TLS cert %s: %v",
36+
name, tlsCertPath, err)
37+
}
38+
39+
opts := []grpc.DialOption{
40+
// From the grpcProxy doc: This codec is *crucial* to the
41+
// functioning of the proxy.
42+
grpc.WithCodec(grpcProxy.Codec()), // nolint
43+
grpc.WithTransportCredentials(tlsConfig),
44+
grpc.WithDefaultCallOptions(maxMsgRecvSize),
45+
grpc.WithConnectParams(grpc.ConnectParams{
46+
Backoff: backoff.DefaultConfig,
47+
MinConnectTimeout: defaultConnectTimeout,
48+
}),
49+
}
50+
51+
log.Infof("Dialing %s gRPC server at %s", name, dialAddr)
52+
cc, err := grpc.Dial(dialAddr, opts...)
53+
if err != nil {
54+
return nil, fmt.Errorf("failed dialing %s backend: %v", name,
55+
err)
56+
}
57+
return cc, nil
58+
}
59+
60+
// dialBufConnBackend dials an in-memory connection to an RPC listener and
61+
// ignores any TLS certificate mismatches.
62+
func dialBufConnBackend(listener *bufconn.Listener) (*grpc.ClientConn, error) {
63+
tlsConfig := credentials.NewTLS(&tls.Config{
64+
InsecureSkipVerify: true,
65+
})
66+
67+
opts := []grpc.DialOption{
68+
grpc.WithContextDialer(
69+
func(context.Context, string) (net.Conn, error) {
70+
return listener.Dial()
71+
},
72+
),
73+
// From the grpcProxy doc: This codec is *crucial* to the
74+
// functioning of the proxy.
75+
grpc.WithCodec(grpcProxy.Codec()), // nolint
76+
grpc.WithTransportCredentials(tlsConfig),
77+
grpc.WithDefaultCallOptions(maxMsgRecvSize),
78+
grpc.WithConnectParams(grpc.ConnectParams{
79+
Backoff: backoff.DefaultConfig,
80+
MinConnectTimeout: defaultConnectTimeout,
81+
}),
82+
}
83+
84+
return grpc.Dial("", opts...)
85+
}

rpc_proxy.go

Lines changed: 3 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ package terminal
22

33
import (
44
"context"
5-
"crypto/tls"
65
"encoding/base64"
76
"encoding/hex"
87
"fmt"
98
"io/ioutil"
10-
"net"
119
"net/http"
1210
"strings"
1311
"sync/atomic"
@@ -21,12 +19,9 @@ import (
2119
"github.com/lightningnetwork/lnd/macaroons"
2220
grpcProxy "github.com/mwitkow/grpc-proxy/proxy"
2321
"google.golang.org/grpc"
24-
"google.golang.org/grpc/backoff"
2522
"google.golang.org/grpc/codes"
26-
"google.golang.org/grpc/credentials"
2723
"google.golang.org/grpc/metadata"
2824
"google.golang.org/grpc/status"
29-
"google.golang.org/grpc/test/bufconn"
3025
"gopkg.in/macaroon.v2"
3126
)
3227

@@ -65,7 +60,7 @@ func (e *proxyErr) Unwrap() error {
6560
// component.
6661
func newRpcProxy(cfg *Config, validator macaroons.MacaroonValidator,
6762
superMacValidator session.SuperMacaroonValidator,
68-
permsMgr *perms.Manager, bufListener *bufconn.Listener) *rpcProxy {
63+
permsMgr *perms.Manager) *rpcProxy {
6964

7065
// The gRPC web calls are protected by HTTP basic auth which is defined
7166
// by base64(username:password). Because we only have a password, we
@@ -85,7 +80,6 @@ func newRpcProxy(cfg *Config, validator macaroons.MacaroonValidator,
8580
permsMgr: permsMgr,
8681
macValidator: validator,
8782
superMacValidator: superMacValidator,
88-
bufListener: bufListener,
8983
}
9084
p.grpcServer = grpc.NewServer(
9185
// From the grpxProxy doc: This codec is *crucial* to the
@@ -162,7 +156,6 @@ type rpcProxy struct {
162156

163157
macValidator macaroons.MacaroonValidator
164158
superMacValidator session.SuperMacaroonValidator
165-
bufListener *bufconn.Listener
166159

167160
superMacaroon string
168161

@@ -176,21 +169,9 @@ type rpcProxy struct {
176169
}
177170

178171
// Start creates initial connection to lnd.
179-
func (p *rpcProxy) Start() error {
172+
func (p *rpcProxy) Start(lndConn *grpc.ClientConn) error {
180173
var err error
181-
182-
// Setup the connection to lnd.
183-
host, _, tlsPath, _, _ := p.cfg.lndConnectParams()
184-
185-
// We use a bufconn to connect to lnd in integrated mode.
186-
if p.cfg.LndMode == ModeIntegrated {
187-
p.lndConn, err = dialBufConnBackend(p.bufListener)
188-
} else {
189-
p.lndConn, err = dialBackend("lnd", host, tlsPath)
190-
}
191-
if err != nil {
192-
return fmt.Errorf("could not dial lnd: %v", err)
193-
}
174+
p.lndConn = lndConn
194175

195176
// Make sure we can connect to all the daemons that are configured to be
196177
// running in remote mode.
@@ -242,13 +223,6 @@ func (p *rpcProxy) hasStarted() bool {
242223
func (p *rpcProxy) Stop() error {
243224
p.grpcServer.Stop()
244225

245-
if p.lndConn != nil {
246-
if err := p.lndConn.Close(); err != nil {
247-
log.Errorf("Error closing lnd connection: %v", err)
248-
return err
249-
}
250-
}
251-
252226
if p.faradayConn != nil {
253227
if err := p.faradayConn.Close(); err != nil {
254228
log.Errorf("Error closing faraday connection: %v", err)
@@ -681,68 +655,6 @@ func (p *rpcProxy) convertSuperMacaroon(ctx context.Context, macHex string,
681655
return nil, nil
682656
}
683657

684-
// dialBufConnBackend dials an in-memory connection to an RPC listener and
685-
// ignores any TLS certificate mismatches.
686-
func dialBufConnBackend(listener *bufconn.Listener) (*grpc.ClientConn, error) {
687-
tlsConfig := credentials.NewTLS(&tls.Config{
688-
InsecureSkipVerify: true,
689-
})
690-
conn, err := grpc.Dial(
691-
"",
692-
grpc.WithContextDialer(
693-
func(context.Context, string) (net.Conn, error) {
694-
return listener.Dial()
695-
},
696-
),
697-
grpc.WithTransportCredentials(tlsConfig),
698-
699-
// From the grpcProxy doc: This codec is *crucial* to the
700-
// functioning of the proxy.
701-
grpc.WithCodec(grpcProxy.Codec()), // nolint
702-
grpc.WithTransportCredentials(tlsConfig),
703-
grpc.WithDefaultCallOptions(maxMsgRecvSize),
704-
grpc.WithConnectParams(grpc.ConnectParams{
705-
Backoff: backoff.DefaultConfig,
706-
MinConnectTimeout: defaultConnectTimeout,
707-
}),
708-
)
709-
710-
return conn, err
711-
}
712-
713-
// dialBackend connects to a gRPC backend through the given address and uses the
714-
// given TLS certificate to authenticate the connection.
715-
func dialBackend(name, dialAddr, tlsCertPath string) (*grpc.ClientConn, error) {
716-
var opts []grpc.DialOption
717-
tlsConfig, err := credentials.NewClientTLSFromFile(tlsCertPath, "")
718-
if err != nil {
719-
return nil, fmt.Errorf("could not read %s TLS cert %s: %v",
720-
name, tlsCertPath, err)
721-
}
722-
723-
opts = append(
724-
opts,
725-
726-
// From the grpcProxy doc: This codec is *crucial* to the
727-
// functioning of the proxy.
728-
grpc.WithCodec(grpcProxy.Codec()), // nolint
729-
grpc.WithTransportCredentials(tlsConfig),
730-
grpc.WithDefaultCallOptions(maxMsgRecvSize),
731-
grpc.WithConnectParams(grpc.ConnectParams{
732-
Backoff: backoff.DefaultConfig,
733-
MinConnectTimeout: defaultConnectTimeout,
734-
}),
735-
)
736-
737-
log.Infof("Dialing %s gRPC server at %s", name, dialAddr)
738-
cc, err := grpc.Dial(dialAddr, opts...)
739-
if err != nil {
740-
return nil, fmt.Errorf("failed dialing %s backend: %v", name,
741-
err)
742-
}
743-
return cc, nil
744-
}
745-
746658
// readMacaroon tries to read the macaroon file at the specified path and create
747659
// gRPC dial options from it.
748660
func readMacaroon(macPath string) ([]byte, error) {

terminal.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ type LightningTerminal struct {
160160
wg sync.WaitGroup
161161
errQueue *queue.ConcurrentQueue[error]
162162

163+
lndConn *grpc.ClientConn
163164
lndClient *lndclient.GrpcLndServices
164165
basicClient lnrpc.LightningClient
165166

@@ -244,7 +245,7 @@ func (g *LightningTerminal) Run() error {
244245
g.loopServer = loopd.New(g.cfg.Loop, nil)
245246
g.poolServer = pool.NewServer(g.cfg.Pool)
246247
g.rpcProxy = newRpcProxy(
247-
g.cfg, g, g.validateSuperMacaroon, g.permsMgr, bufRpcListener,
248+
g.cfg, g, g.validateSuperMacaroon, g.permsMgr,
248249
)
249250
g.accountService, err = accounts.NewService(
250251
filepath.Dir(g.cfg.MacaroonPath), g.errQueue.ChanIn(),
@@ -436,11 +437,17 @@ func (g *LightningTerminal) Run() error {
436437
}
437438
}()
438439

440+
// Connect to LND.
441+
g.lndConn, err = connectLND(g.cfg, bufRpcListener)
442+
if err != nil {
443+
return fmt.Errorf("could not connect to LND: %v", err)
444+
}
445+
439446
// Now start the RPC proxy that will handle all incoming gRPC, grpc-web
440447
// and REST requests. We also start the main web server that dispatches
441448
// requests either to the static UI file server or the RPC proxy. This
442449
// makes it possible to unlock lnd through the UI.
443-
if err := g.rpcProxy.Start(); err != nil {
450+
if err := g.rpcProxy.Start(g.lndConn); err != nil {
444451
return fmt.Errorf("error starting lnd gRPC proxy server: %v",
445452
err)
446453
}
@@ -1178,6 +1185,13 @@ func (g *LightningTerminal) shutdown() error {
11781185
}
11791186
}
11801187

1188+
if g.lndConn != nil {
1189+
if err := g.lndConn.Close(); err != nil {
1190+
log.Errorf("Error closing lnd connection: %v", err)
1191+
returnErr = err
1192+
}
1193+
}
1194+
11811195
if g.httpServer != nil {
11821196
if err := g.httpServer.Close(); err != nil {
11831197
log.Errorf("Error stopping UI server: %v", err)

0 commit comments

Comments
 (0)