@@ -3,6 +3,7 @@ package aperture
3
3
import (
4
4
"context"
5
5
"crypto/tls"
6
+ "database/sql"
6
7
"errors"
7
8
"fmt"
8
9
"io"
@@ -17,6 +18,7 @@ import (
17
18
grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
18
19
gateway "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
19
20
flags "github.com/jessevdk/go-flags"
21
+ "github.com/lightninglabs/aperture/aperturedb"
20
22
"github.com/lightninglabs/aperture/auth"
21
23
"github.com/lightninglabs/aperture/mint"
22
24
"github.com/lightninglabs/aperture/proxy"
@@ -160,6 +162,7 @@ type Aperture struct {
160
162
cfg * Config
161
163
162
164
etcdClient * clientv3.Client
165
+ db * sql.DB
163
166
challenger * LndChallenger
164
167
httpsServer * http.Server
165
168
torHTTPServer * http.Server
@@ -208,17 +211,79 @@ func (a *Aperture) Start(errChan chan error) error {
208
211
}()
209
212
}
210
213
211
- // Initialize our etcd client.
212
- a .etcdClient , err = clientv3 .New (clientv3.Config {
213
- Endpoints : []string {a .cfg .Etcd .Host },
214
- DialTimeout : 5 * time .Second ,
215
- Username : a .cfg .Etcd .User ,
216
- Password : a .cfg .Etcd .Password ,
217
- })
218
- if err != nil {
219
- return fmt .Errorf ("unable to connect to etcd: %v" , err )
214
+ var (
215
+ secretStore mint.SecretStore
216
+ onionStore tor.OnionStore
217
+ )
218
+
219
+ // Connect to the chosen database backend.
220
+ switch a .cfg .DatabaseBackend {
221
+ case "etcd" :
222
+ // Initialize our etcd client.
223
+ a .etcdClient , err = clientv3 .New (clientv3.Config {
224
+ Endpoints : []string {a .cfg .Etcd .Host },
225
+ DialTimeout : 5 * time .Second ,
226
+ Username : a .cfg .Etcd .User ,
227
+ Password : a .cfg .Etcd .Password ,
228
+ })
229
+ if err != nil {
230
+ return fmt .Errorf ("unable to connect to etcd: %v" , err )
231
+ }
232
+
233
+ secretStore = newSecretStore (a .etcdClient )
234
+ onionStore = newOnionStore (a .etcdClient )
235
+
236
+ case "postgres" :
237
+ db , err := aperturedb .NewPostgresStore (a .cfg .Postgres )
238
+ if err != nil {
239
+ return fmt .Errorf ("unable to connect to postgres: %v" ,
240
+ err )
241
+ }
242
+ a .db = db .DB
243
+
244
+ dbSecretTxer := aperturedb .NewTransactionExecutor (db ,
245
+ func (tx * sql.Tx ) aperturedb.SecretsDB {
246
+ return db .WithTx (tx )
247
+ },
248
+ )
249
+ secretStore = aperturedb .NewSecretsStore (dbSecretTxer )
250
+
251
+ dbOnionTxer := aperturedb .NewTransactionExecutor (db ,
252
+ func (tx * sql.Tx ) aperturedb.OnionDB {
253
+ return db .WithTx (tx )
254
+ },
255
+ )
256
+ onionStore = aperturedb .NewOnionStore (dbOnionTxer )
257
+
258
+ case "sqlite" :
259
+ db , err := aperturedb .NewSqliteStore (a .cfg .Sqlite )
260
+ if err != nil {
261
+ return fmt .Errorf ("unable to connect to sqlite: %v" ,
262
+ err )
263
+ }
264
+ a .db = db .DB
265
+
266
+ dbSecretTxer := aperturedb .NewTransactionExecutor (db ,
267
+ func (tx * sql.Tx ) aperturedb.SecretsDB {
268
+ return db .WithTx (tx )
269
+ },
270
+ )
271
+ secretStore = aperturedb .NewSecretsStore (dbSecretTxer )
272
+
273
+ dbOnionTxer := aperturedb .NewTransactionExecutor (db ,
274
+ func (tx * sql.Tx ) aperturedb.OnionDB {
275
+ return db .WithTx (tx )
276
+ },
277
+ )
278
+ onionStore = aperturedb .NewOnionStore (dbOnionTxer )
279
+
280
+ default :
281
+ return fmt .Errorf ("unknown database backend: %s" ,
282
+ a .cfg .DatabaseBackend )
220
283
}
221
284
285
+ log .Infof ("Using %v as database backend" , a .cfg .DatabaseBackend )
286
+
222
287
// Create our challenger that uses our backing lnd node to create
223
288
// invoices and check their settlement status.
224
289
genInvoiceReq := func (price int64 ) (* lnrpc.Invoice , error ) {
@@ -243,7 +308,7 @@ func (a *Aperture) Start(errChan chan error) error {
243
308
244
309
// Create the proxy and connect it to lnd.
245
310
a .proxy , a .proxyCleanup , err = createProxy (
246
- a .cfg , a .challenger , a . etcdClient ,
311
+ a .cfg , a .challenger , secretStore ,
247
312
)
248
313
if err != nil {
249
314
return err
@@ -304,7 +369,7 @@ func (a *Aperture) Start(errChan chan error) error {
304
369
// provide encryption, so running this additional HTTP server should be
305
370
// relatively safe.
306
371
if a .cfg .Tor .V3 {
307
- torController , err := initTorListener (a .cfg , a . etcdClient )
372
+ torController , err := initTorListener (a .cfg , onionStore )
308
373
if err != nil {
309
374
return err
310
375
}
@@ -351,14 +416,31 @@ func (a *Aperture) Stop() error {
351
416
a .proxyCleanup ()
352
417
}
353
418
419
+ if a .etcdClient != nil {
420
+ if err := a .etcdClient .Close (); err != nil {
421
+ log .Errorf ("Error terminating etcd client: %v" , err )
422
+ returnErr = err
423
+ }
424
+ }
425
+
426
+ if a .db != nil {
427
+ if err := a .db .Close (); err != nil {
428
+ log .Errorf ("Error closing database: %v" , err )
429
+ returnErr = err
430
+ }
431
+ }
432
+
354
433
// Shut down our client and server connections now. This should cause
355
434
// the first goroutine to quit.
356
- cleanup (a .etcdClient , a . httpsServer , a .proxy )
435
+ cleanup (a .httpsServer , a .proxy )
357
436
358
437
// If we started a tor server as well, shut it down now too to cause the
359
438
// second goroutine to quit.
360
439
if a .torHTTPServer != nil {
361
- returnErr = a .torHTTPServer .Close ()
440
+ if err := a .torHTTPServer .Close (); err != nil {
441
+ log .Errorf ("Error stopping tor server: %v" , err )
442
+ returnErr = err
443
+ }
362
444
}
363
445
364
446
// Now we wait for the goroutines to exit before we return. The defers
@@ -628,13 +710,15 @@ func getTLSConfig(serverName, baseDir string, autoCert bool) (
628
710
// initTorListener initiates a Tor controller instance with the Tor server
629
711
// specified in the config. Onion services will be created over which the proxy
630
712
// can be reached at.
631
- func initTorListener (cfg * Config , etcd * clientv3.Client ) (* tor.Controller , error ) {
713
+ func initTorListener (cfg * Config , store tor.OnionStore ) (* tor.Controller ,
714
+ error ) {
715
+
632
716
// Establish a controller connection with the backing Tor server and
633
717
// proceed to create the requested onion services.
634
718
onionCfg := tor.AddOnionConfig {
635
719
VirtualPort : int (cfg .Tor .VirtualPort ),
636
720
TargetPorts : []int {int (cfg .Tor .ListenPort )},
637
- Store : newOnionStore ( etcd ) ,
721
+ Store : store ,
638
722
}
639
723
torController := tor .NewController (cfg .Tor .Control , "" , "" )
640
724
if err := torController .Start (); err != nil {
@@ -656,11 +740,11 @@ func initTorListener(cfg *Config, etcd *clientv3.Client) (*tor.Controller, error
656
740
657
741
// createProxy creates the proxy with all the services it needs.
658
742
func createProxy (cfg * Config , challenger * LndChallenger ,
659
- etcdClient * clientv3. Client ) (* proxy.Proxy , func (), error ) {
743
+ store mint. SecretStore ) (* proxy.Proxy , func (), error ) {
660
744
661
745
minter := mint .New (& mint.Config {
662
746
Challenger : challenger ,
663
- Secrets : newSecretStore ( etcdClient ) ,
747
+ Secrets : store ,
664
748
ServiceLimiter : newStaticServiceLimiter (cfg .Services ),
665
749
Now : time .Now ,
666
750
})
@@ -817,13 +901,10 @@ func createHashMailServer(cfg *Config) ([]proxy.LocalService, func(), error) {
817
901
}
818
902
819
903
// cleanup closes the given server and shuts down the log rotator.
820
- func cleanup (etcdClient io. Closer , server io.Closer , proxy io.Closer ) {
904
+ func cleanup (server io.Closer , proxy io.Closer ) {
821
905
if err := proxy .Close (); err != nil {
822
906
log .Errorf ("Error terminating proxy: %v" , err )
823
907
}
824
- if err := etcdClient .Close (); err != nil {
825
- log .Errorf ("Error terminating etcd client: %v" , err )
826
- }
827
908
err := server .Close ()
828
909
if err != nil {
829
910
log .Errorf ("Error closing server: %v" , err )
0 commit comments