Skip to content

Commit 5e00ce6

Browse files
authored
Merge pull request #115 from halseth/loopd-mobile
Create loopd package, allow custom listeners
2 parents 1ea58ad + 0a51bf4 commit 5e00ce6

File tree

13 files changed

+262
-152
lines changed

13 files changed

+262
-152
lines changed

.gitignore

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,6 @@ output*.log
2929
loop
3030
!cmd/loop/
3131

32-
loopd
33-
!cmd/loopd/
34-
3532
*.key
3633
*.hex
3734

cmd/loopd/main.go

Lines changed: 3 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -2,118 +2,14 @@ package main
22

33
import (
44
"fmt"
5-
"os"
6-
"path/filepath"
7-
"strings"
8-
"sync"
95

10-
"github.com/jessevdk/go-flags"
11-
"github.com/lightninglabs/loop"
12-
"github.com/lightningnetwork/lnd/build"
13-
"github.com/lightningnetwork/lnd/lntypes"
14-
)
15-
16-
const (
17-
defaultConfTarget = int32(6)
18-
)
19-
20-
var (
21-
defaultConfigFilename = "loopd.conf"
22-
23-
swaps = make(map[lntypes.Hash]loop.SwapInfo)
24-
subscribers = make(map[int]chan<- interface{})
25-
nextSubscriberID int
26-
swapsLock sync.Mutex
6+
"github.com/lightninglabs/loop/loopd"
277
)
288

299
func main() {
30-
err := start()
10+
cfg := loopd.RPCConfig{}
11+
err := loopd.Start(cfg)
3112
if err != nil {
3213
fmt.Println(err)
3314
}
3415
}
35-
36-
func start() error {
37-
config := defaultConfig
38-
39-
// Parse command line flags.
40-
parser := flags.NewParser(&config, flags.Default)
41-
parser.SubcommandsOptional = true
42-
43-
_, err := parser.Parse()
44-
if e, ok := err.(*flags.Error); ok && e.Type == flags.ErrHelp {
45-
return nil
46-
}
47-
if err != nil {
48-
return err
49-
}
50-
51-
// Parse ini file.
52-
loopDir := filepath.Join(loopDirBase, config.Network)
53-
if err := os.MkdirAll(loopDir, os.ModePerm); err != nil {
54-
return err
55-
}
56-
57-
configFile := filepath.Join(loopDir, defaultConfigFilename)
58-
if err := flags.IniParse(configFile, &config); err != nil {
59-
// If it's a parsing related error, then we'll return
60-
// immediately, otherwise we can proceed as possibly the config
61-
// file doesn't exist which is OK.
62-
if _, ok := err.(*flags.IniError); ok {
63-
return err
64-
}
65-
}
66-
67-
// Parse command line flags again to restore flags overwritten by ini
68-
// parse.
69-
_, err = parser.Parse()
70-
if err != nil {
71-
return err
72-
}
73-
74-
// Show the version and exit if the version flag was specified.
75-
appName := filepath.Base(os.Args[0])
76-
appName = strings.TrimSuffix(appName, filepath.Ext(appName))
77-
if config.ShowVersion {
78-
fmt.Println(appName, "version", loop.Version())
79-
os.Exit(0)
80-
}
81-
82-
// Special show command to list supported subsystems and exit.
83-
if config.DebugLevel == "show" {
84-
fmt.Printf("Supported subsystems: %v\n",
85-
logWriter.SupportedSubsystems())
86-
os.Exit(0)
87-
}
88-
89-
// Append the network type to the log directory so it is
90-
// "namespaced" per network in the same fashion as the data directory.
91-
config.LogDir = filepath.Join(config.LogDir, config.Network)
92-
93-
// Initialize logging at the default logging level.
94-
err = logWriter.InitLogRotator(
95-
filepath.Join(config.LogDir, defaultLogFilename),
96-
config.MaxLogFileSize, config.MaxLogFiles,
97-
)
98-
if err != nil {
99-
return err
100-
}
101-
err = build.ParseAndSetDebugLevels(config.DebugLevel, logWriter)
102-
if err != nil {
103-
return err
104-
}
105-
106-
// Print the version before executing either primary directive.
107-
log.Infof("Version: %v", loop.Version())
108-
109-
// Execute command.
110-
if parser.Active == nil {
111-
return daemon(&config)
112-
}
113-
114-
if parser.Active.Name == "view" {
115-
return view(&config)
116-
}
117-
118-
return fmt.Errorf("unimplemented command %v", parser.Active.Name)
119-
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ require (
1010
github.com/google/go-cmp v0.3.1 // indirect
1111
github.com/grpc-ecosystem/grpc-gateway v1.10.0
1212
github.com/jessevdk/go-flags v1.4.0
13-
github.com/lightningnetwork/lnd v0.8.0-beta-rc3.0.20191212054348-dca31c2bf8be
13+
github.com/lightningnetwork/lnd v0.8.0-beta-rc3.0.20200103000305-22e1f006b194
1414
github.com/lightningnetwork/lnd/queue v1.0.2
1515
github.com/urfave/cli v1.20.0
1616
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 // indirect

go.sum

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,11 @@ github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf h1:HZKvJUHlcXI
136136
github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf/go.mod h1:vxmQPeIQxPf6Jf9rM8R+B4rKBqLA2AjttNxkFBL2Plk=
137137
github.com/lightninglabs/neutrino v0.11.0 h1:lPpYFCtsfJX2W5zI4pWycPmbbBdr7zU+BafYdLoD6k0=
138138
github.com/lightninglabs/neutrino v0.11.0/go.mod h1:CuhF0iuzg9Sp2HO6ZgXgayviFTn1QHdSTJlMncK80wg=
139-
github.com/lightningnetwork/lightning-onion v0.0.0-20190909101754-850081b08b6a h1:GoWPN4i4jTKRxhVNh9a2vvBBO1Y2seiJB+SopUYoKyo=
140-
github.com/lightningnetwork/lightning-onion v0.0.0-20190909101754-850081b08b6a/go.mod h1:rigfi6Af/KqsF7Za0hOgcyq2PNH4AN70AaMRxcJkff4=
141-
github.com/lightningnetwork/lnd v0.8.0-beta-rc3.0.20191212054348-dca31c2bf8be h1:CX8ScoYxJju6AcceHY6nATfRLThZpewqHcgn4sGMdZE=
142-
github.com/lightningnetwork/lnd v0.8.0-beta-rc3.0.20191212054348-dca31c2bf8be/go.mod h1:60/zDjDYaYPmISAm3J1WWKyyt+ZiAvuET1XzglO8s70=
139+
github.com/lightninglabs/protobuf-hex-display v1.3.3-0.20191212020323-b444784ce75d/go.mod h1:KDb67YMzoh4eudnzClmvs2FbiLG9vxISmLApUkCa4uI=
140+
github.com/lightningnetwork/lightning-onion v0.0.0-20191214001659-f34e9dc1651d h1:U50MHOOeL6gR3Ee/l0eMvZMpmRo+ydzmlQuIruCyCsA=
141+
github.com/lightningnetwork/lightning-onion v0.0.0-20191214001659-f34e9dc1651d/go.mod h1:rigfi6Af/KqsF7Za0hOgcyq2PNH4AN70AaMRxcJkff4=
142+
github.com/lightningnetwork/lnd v0.8.0-beta-rc3.0.20200103000305-22e1f006b194 h1:PCzjJcVWcMbkiQvzFNc3ta0JmiMprFDqzMZsSpd/km8=
143+
github.com/lightningnetwork/lnd v0.8.0-beta-rc3.0.20200103000305-22e1f006b194/go.mod h1:WHK90FD3m2n6OyWzondS7ho0Uhtgfp30Nxvj24lQYX4=
143144
github.com/lightningnetwork/lnd/cert v1.0.0 h1:J0gtf2UNQX2U+/j5cXnX2wIMSTuJuwrXv7m9qJr2wtw=
144145
github.com/lightningnetwork/lnd/cert v1.0.0/go.mod h1:fmtemlSMf5t4hsQmcprSoOykypAPp+9c+0d0iqTScMo=
145146
github.com/lightningnetwork/lnd/queue v1.0.1 h1:jzJKcTy3Nj5lQrooJ3aaw9Lau3I0IwvQR5sqtjdv2R0=

lndclient/basic_client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func NewBasicClient(lndHost, tlsPath, macDir, network string, basicOptions ...Ba
103103
// We need to use a custom dialer so we can also connect to unix sockets
104104
// and not just TCP addresses.
105105
opts = append(
106-
opts, grpc.WithDialer(
106+
opts, grpc.WithContextDialer(
107107
lncfg.ClientAddressDialer(defaultRPCPort),
108108
),
109109
)

lndclient/lnd_services.go

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"net"
78
"path/filepath"
89
"time"
910

@@ -38,9 +39,24 @@ type GrpcLndServices struct {
3839
cleanup func()
3940
}
4041

41-
// NewLndServices creates a set of required RPC services.
42-
func NewLndServices(lndAddress, application, network, macaroonDir,
43-
tlsPath string) (*GrpcLndServices, error) {
42+
// NewLndServices creates creates a connection to the given lnd instance and
43+
// creates a set of required RPC services.
44+
func NewLndServices(lndAddress, network, macaroonDir, tlsPath string) (
45+
*GrpcLndServices, error) {
46+
47+
// We need to use a custom dialer so we can also connect to unix
48+
// sockets and not just TCP addresses.
49+
dialer := lncfg.ClientAddressDialer(defaultRPCPort)
50+
51+
return NewLndServicesWithDialer(
52+
dialer, lndAddress, network, macaroonDir, tlsPath,
53+
)
54+
}
55+
56+
// NewLndServices creates a set of required RPC services by connecting to lnd
57+
// using the given dialer.
58+
func NewLndServicesWithDialer(dialer dialerFunc, lndAddress, network,
59+
macaroonDir, tlsPath string) (*GrpcLndServices, error) {
4460

4561
// Based on the network, if the macaroon directory isn't set, then
4662
// we'll use the expected default locations.
@@ -85,7 +101,7 @@ func NewLndServices(lndAddress, application, network, macaroonDir,
85101

86102
// Setup connection with lnd
87103
log.Infof("Creating lnd connection to %v", lndAddress)
88-
conn, err := getClientConn(lndAddress, network, tlsPath)
104+
conn, err := getClientConn(dialer, lndAddress, tlsPath)
89105
if err != nil {
90106
return nil, err
91107
}
@@ -189,7 +205,9 @@ var (
189205
maxMsgRecvSize = grpc.MaxCallRecvMsgSize(1 * 1024 * 1024 * 200)
190206
)
191207

192-
func getClientConn(address string, network string, tlsPath string) (
208+
type dialerFunc func(context.Context, string) (net.Conn, error)
209+
210+
func getClientConn(dialer dialerFunc, address string, tlsPath string) (
193211
*grpc.ClientConn, error) {
194212

195213
// Load the specified TLS certificate and build transport credentials
@@ -206,15 +224,12 @@ func getClientConn(address string, network string, tlsPath string) (
206224
// Create a dial options array.
207225
opts := []grpc.DialOption{
208226
grpc.WithTransportCredentials(creds),
227+
228+
// Use a custom dialer, to allow connections to unix sockets,
229+
// in-memory listeners etc, and not just TCP addresses.
230+
grpc.WithContextDialer(dialer),
209231
}
210232

211-
// We need to use a custom dialer so we can also connect to unix sockets
212-
// and not just TCP addresses.
213-
opts = append(
214-
opts, grpc.WithDialer(
215-
lncfg.ClientAddressDialer(defaultRPCPort),
216-
),
217-
)
218233
conn, err := grpc.Dial(address, opts...)
219234
if err != nil {
220235
return nil, fmt.Errorf("unable to connect to RPC server: %v", err)

cmd/loopd/config.go renamed to loopd/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package main
1+
package loopd
22

33
import (
44
"path/filepath"

cmd/loopd/daemon.go renamed to loopd/daemon.go

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package main
1+
package loopd
22

33
import (
44
"context"
@@ -14,14 +14,27 @@ import (
1414

1515
proxy "github.com/grpc-ecosystem/grpc-gateway/runtime"
1616
"github.com/lightninglabs/loop"
17+
"github.com/lightninglabs/loop/lndclient"
1718
"github.com/lightninglabs/loop/looprpc"
1819
"google.golang.org/grpc"
1920
)
2021

22+
// listenerCfg holds closures used to retrieve listeners for the gRPC services.
23+
type listenerCfg struct {
24+
// grpcListener returns a listener to use for the gRPC server.
25+
grpcListener func() (net.Listener, error)
26+
27+
// restListener returns a listener to use for the REST proxy.
28+
restListener func() (net.Listener, error)
29+
30+
// getLnd returns a grpc connection to an lnd instance.
31+
getLnd func(string, *lndConfig) (*lndclient.GrpcLndServices, error)
32+
}
33+
2134
// daemon runs loopd in daemon mode. It will listen for grpc connections,
2235
// execute commands and pass back swap status information.
23-
func daemon(config *config) error {
24-
lnd, err := getLnd(config.Network, config.Lnd)
36+
func daemon(config *config, lisCfg *listenerCfg) error {
37+
lnd, err := lisCfg.getLnd(config.Network, config.Lnd)
2538
if err != nil {
2639
return err
2740
}
@@ -74,7 +87,7 @@ func daemon(config *config) error {
7487

7588
// Next, start the gRPC server listening for HTTP/2 connections.
7689
log.Infof("Starting gRPC listener")
77-
grpcListener, err := net.Listen("tcp", config.RPCListen)
90+
grpcListener, err := lisCfg.grpcListener()
7891
if err != nil {
7992
return fmt.Errorf("RPC server unable to listen on %s",
8093
config.RPCListen)
@@ -95,15 +108,30 @@ func daemon(config *config) error {
95108
return err
96109
}
97110

98-
log.Infof("Starting REST proxy listener")
99-
restListener, err := net.Listen("tcp", config.RESTListen)
111+
restListener, err := lisCfg.restListener()
100112
if err != nil {
101113
return fmt.Errorf("REST proxy unable to listen on %s",
102114
config.RESTListen)
103115
}
104-
defer restListener.Close()
105-
proxy := &http.Server{Handler: mux}
106-
go proxy.Serve(restListener)
116+
117+
// A nil listener indicates REST is disabled.
118+
if restListener != nil {
119+
log.Infof("Starting REST proxy listener")
120+
121+
defer restListener.Close()
122+
proxy := &http.Server{Handler: mux}
123+
124+
go func() {
125+
err := proxy.Serve(restListener)
126+
// ErrServerClosed is always returned when the proxy is
127+
// shut down, so don't log it.
128+
if err != nil && err != http.ErrServerClosed {
129+
log.Error(err)
130+
}
131+
}()
132+
} else {
133+
log.Infof("REST proxy disabled")
134+
}
107135

108136
statusChan := make(chan loop.SwapInfo)
109137

@@ -161,7 +189,10 @@ func daemon(config *config) error {
161189
defer wg.Done()
162190

163191
log.Infof("RPC server listening on %s", grpcListener.Addr())
164-
log.Infof("REST proxy listening on %s", restListener.Addr())
192+
193+
if restListener != nil {
194+
log.Infof("REST proxy listening on %s", restListener.Addr())
195+
}
165196

166197
err = grpcServer.Serve(grpcListener)
167198
if err != nil {

cmd/loopd/log.go renamed to loopd/log.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package main
1+
package loopd
22

33
import (
44
"github.com/btcsuite/btclog"

0 commit comments

Comments
 (0)