Skip to content

Commit 427fd98

Browse files
committed
migratedb: add sqlite possibility
1 parent 549108b commit 427fd98

File tree

1 file changed

+144
-34
lines changed

1 file changed

+144
-34
lines changed

cmd_migrate_db.go

+144-34
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@ import (
88
"strconv"
99
"time"
1010

11+
"github.com/btcsuite/btcd/btcutil"
1112
"github.com/btcsuite/btcwallet/walletdb"
1213
"github.com/jessevdk/go-flags"
1314
"github.com/lightningnetwork/lnd/channeldb"
1415
"github.com/lightningnetwork/lnd/kvdb"
1516
"github.com/lightningnetwork/lnd/kvdb/etcd"
1617
"github.com/lightningnetwork/lnd/kvdb/postgres"
18+
"github.com/lightningnetwork/lnd/kvdb/sqlbase"
19+
"github.com/lightningnetwork/lnd/kvdb/sqlite"
1720
"github.com/lightningnetwork/lnd/lncfg"
1821
"github.com/lightningnetwork/lnd/signal"
1922
clientv3 "go.etcd.io/etcd/client/v3"
@@ -27,6 +30,9 @@ var (
2730

2831
// etcdTimeout is the time we allow a single etcd transaction to take.
2932
etcdTimeout = time.Second * 5
33+
34+
// defaultDataDir is the default data directory for lnd.
35+
defaultDataDir = btcutil.AppDataDir("lnd", false)
3036
)
3137

3238
const (
@@ -40,28 +46,51 @@ type Bolt struct {
4046
DBTimeout time.Duration `long:"dbtimeout" description:"Specify the timeout value used when opening the database."`
4147
DataDir string `long:"data-dir" description:"Lnd data dir where bolt dbs are located."`
4248
TowerDir string `long:"tower-dir" description:"Lnd watchtower dir where bolt dbs for the watchtower server are located."`
43-
Network string `long:"network" description:"Network within data dir where bolt dbs are located."`
49+
}
50+
51+
type Sqlite struct {
52+
DataDir string `long:"data-dir" description:"Lnd data dir where sqlite dbs are located."`
53+
TowerDir string `long:"tower-dir" description:"Lnd watchtower dir where sqlite dbs for the watchtower server are located."`
54+
Config *sqlite.Config `group:"sqlite-config" namespace:"sqlite-config" description:"Sqlite config."`
4455
}
4556

4657
type DB struct {
4758
Backend string `long:"backend" description:"The selected database backend."`
4859
Etcd *etcd.Config `group:"etcd" namespace:"etcd" description:"Etcd settings."`
4960
Bolt *Bolt `group:"bolt" namespace:"bolt" description:"Bolt settings."`
5061
Postgres *postgres.Config `group:"postgres" namespace:"postgres" description:"Postgres settings."`
62+
Sqlite *Sqlite `group:"sqlite" namespace:"sqlite" description:"Sqlite settings."`
5163
}
5264

53-
func (d *DB) isRemote() bool {
54-
return d.Backend == lncfg.EtcdBackend ||
55-
d.Backend == lncfg.PostgresBackend
65+
// Init should be called upon start to pre-initialize database for sql
66+
// backends. If max connections are not set, the amount of connections will be
67+
// unlimited however we only use one connection during the migration.
68+
func (db *DB) Init() error {
69+
// Start embedded etcd server if requested.
70+
switch {
71+
case db.Backend == lncfg.PostgresBackend:
72+
sqlbase.Init(db.Postgres.MaxConnections)
73+
74+
case db.Backend == lncfg.SqliteBackend:
75+
sqlbase.Init(db.Sqlite.Config.MaxConnections)
76+
}
77+
78+
return nil
5679
}
5780

58-
func (d *DB) isEtcd() bool {
59-
return d.Backend == lncfg.EtcdBackend
81+
// isBoltDB returns true if the db is a type bolt db.
82+
func (db *DB) isBoltDB() bool {
83+
return db.Backend == lncfg.BoltBackend
84+
}
85+
86+
func (db *DB) isEtcd() bool {
87+
return db.Backend == lncfg.EtcdBackend
6088
}
6189

6290
type migrateDBCommand struct {
63-
Source *DB `group:"source" namespace:"source" long:"source" short:"s" description:"The source database where the data is read from"`
64-
Dest *DB `group:"dest" namespace:"dest" long:"dest" short:"d" description:"The destination database where the data is written to"`
91+
Source *DB `group:"source" namespace:"source" long:"source" short:"s" description:"The source database where the data is read from"`
92+
Dest *DB `group:"dest" namespace:"dest" long:"dest" short:"d" description:"The destination database where the data is written to"`
93+
Network string `long:"network" short:"n" description:"Network of the db files to migrate (used to navigate into the right directory)"`
6594
}
6695

6796
func newMigrateDBCommand() *migrateDBCommand {
@@ -71,9 +100,15 @@ func newMigrateDBCommand() *migrateDBCommand {
71100
Etcd: &etcd.Config{},
72101
Bolt: &Bolt{
73102
DBTimeout: kvdb.DefaultDBTimeout,
74-
Network: "mainnet",
103+
TowerDir: defaultDataDir,
104+
DataDir: defaultDataDir,
75105
},
76106
Postgres: &postgres.Config{},
107+
Sqlite: &Sqlite{
108+
Config: &sqlite.Config{},
109+
TowerDir: defaultDataDir,
110+
DataDir: defaultDataDir,
111+
},
77112
},
78113
Dest: &DB{
79114
Backend: lncfg.EtcdBackend,
@@ -82,10 +117,17 @@ func newMigrateDBCommand() *migrateDBCommand {
82117
},
83118
Bolt: &Bolt{
84119
DBTimeout: kvdb.DefaultDBTimeout,
85-
Network: "mainnet",
120+
TowerDir: defaultDataDir,
121+
DataDir: defaultDataDir,
86122
},
87123
Postgres: &postgres.Config{},
124+
Sqlite: &Sqlite{
125+
Config: &sqlite.Config{},
126+
TowerDir: defaultDataDir,
127+
DataDir: defaultDataDir,
128+
},
88129
},
130+
Network: "regtest",
89131
}
90132
}
91133

@@ -141,20 +183,21 @@ func (x *migrateDBCommand) Execute(_ []string) error {
141183
for _, prefix := range prefixes {
142184
log("Migrating DB with prefix %s", prefix)
143185

144-
srcDb, err := openDb(x.Source, prefix)
145-
if err != nil {
146-
if err == walletdb.ErrDbDoesNotExist &&
147-
x.Source.Backend == lncfg.BoltBackend {
186+
srcDb, err := openDb(x.Source, prefix, x.Network)
148187

149-
log("Skipping DB with prefix %s because "+
150-
"source does not exist", prefix)
151-
continue
152-
}
153-
return err
188+
// This is only for now done for bolt dbs because other backends
189+
// do not special case this error for now. For example if
190+
// we do not run the watcher tower functionaliy we might not
191+
// have a towerclient.db so we skip this error.
192+
if err == walletdb.ErrDbDoesNotExist &&
193+
x.Source.Backend == lncfg.BoltBackend {
194+
195+
log("Skipping DB with prefix %s because "+
196+
"source does not exist", prefix)
197+
continue
154198
}
155-
log("Opened source DB")
156199

157-
destDb, err := openDb(x.Dest, prefix)
200+
destDb, err := openDb(x.Dest, prefix, x.Network)
158201
if err != nil {
159202
return err
160203
}
@@ -183,11 +226,15 @@ func (x *migrateDBCommand) Execute(_ []string) error {
183226
// to the channel DB as that is the only DB that has migrations.
184227
log("Checking DB version of source DB")
185228
if prefix == lncfg.NSChannelDB {
186-
if err := checkMigrationsApplied(srcDb); err != nil {
229+
err := checkChannelDBMigrationsApplied(srcDb)
230+
if err != nil {
187231
return err
188232
}
189233
}
190234

235+
// TODO(ziggie): Also check other DBs for migrations like the
236+
// wtclient.db as soon as LND 19 is tagged.
237+
191238
// Also make sure that the destination DB hasn't been marked as
192239
// successfully having been the target of a migration. We only
193240
// mark a destination DB as successfully migrated at the end of
@@ -286,7 +333,9 @@ func (x *migrateDBCommand) migrateKvdb(srcTx walletdb.ReadWriteTx,
286333
}
287334

288335
// Migrate wallet created marker.
289-
if prefix == lncfg.NSWalletDB && x.Dest.isRemote() {
336+
//
337+
// TODO(ziggie): Why not for bbolt backends ?
338+
if prefix == lncfg.NSWalletDB && !x.Dest.isBoltDB() {
290339
const (
291340
walletMetaBucket = "lnwallet"
292341
walletReadyKey = "ready"
@@ -382,21 +431,27 @@ func (x *migrateDBCommand) migrateEtcd(srcTx walletdb.ReadWriteTx,
382431
return nil
383432
}
384433

385-
func openDb(cfg *DB, prefix string) (walletdb.DB, error) {
434+
func openDb(cfg *DB, prefix, network string) (walletdb.DB, error) {
386435
backend := cfg.Backend
387436

388-
var args []interface{}
437+
// Init the db connections for sql backends.
438+
cfg.Init()
389439

390-
graphDir := filepath.Join(cfg.Bolt.DataDir, "graph", cfg.Bolt.Network)
391-
walletDir := filepath.Join(
392-
cfg.Bolt.DataDir, "chain", "bitcoin", cfg.Bolt.Network,
393-
)
394-
towerServerDir := filepath.Join(
395-
cfg.Bolt.TowerDir, "bitcoin", cfg.Bolt.Network,
396-
)
440+
// Settings to open a particular db backend.
441+
var args []interface{}
397442

398443
switch backend {
399444
case lncfg.BoltBackend:
445+
// Directories where the db files are located.
446+
graphDir := filepath.Join(cfg.Bolt.DataDir, "graph", network)
447+
walletDir := filepath.Join(
448+
cfg.Bolt.DataDir, "chain", "bitcoin", network,
449+
)
450+
towerServerDir := filepath.Join(
451+
cfg.Bolt.TowerDir, "bitcoin", network,
452+
)
453+
454+
// Path to the db file.
400455
var path string
401456
switch prefix {
402457
case lncfg.NSChannelDB:
@@ -443,13 +498,68 @@ func openDb(cfg *DB, prefix string) (walletdb.DB, error) {
443498
args = []interface{}{
444499
context.Background(),
445500
&postgres.Config{
446-
Dsn: cfg.Postgres.Dsn,
501+
Dsn: cfg.Postgres.Dsn,
502+
Timeout: time.Minute,
503+
MaxConnections: 10,
447504
},
448505
prefix,
449506
}
507+
450508
log("Opening postgres backend at %s with prefix '%s'",
451509
cfg.Postgres.Dsn, prefix)
452510

511+
case kvdb.SqliteBackendName:
512+
// Directories where the db files are located.
513+
graphDir := filepath.Join(cfg.Sqlite.DataDir, "graph", network)
514+
walletDir := filepath.Join(
515+
cfg.Sqlite.DataDir, "chain", "bitcoin", network,
516+
)
517+
towerServerDir := filepath.Join(
518+
cfg.Sqlite.TowerDir, "bitcoin", network,
519+
)
520+
521+
var dbName string
522+
var path string
523+
switch prefix {
524+
case lncfg.NSChannelDB:
525+
path = graphDir
526+
dbName = lncfg.SqliteChannelDBName
527+
case lncfg.NSMacaroonDB:
528+
path = walletDir
529+
dbName = lncfg.SqliteChainDBName
530+
531+
case lncfg.NSDecayedLogDB:
532+
path = graphDir
533+
dbName = lncfg.SqliteChannelDBName
534+
535+
case lncfg.NSTowerClientDB:
536+
path = graphDir
537+
dbName = lncfg.SqliteChannelDBName
538+
539+
case lncfg.NSTowerServerDB:
540+
path = towerServerDir
541+
dbName = lncfg.SqliteChannelDBName
542+
543+
case lncfg.NSWalletDB:
544+
path = walletDir
545+
dbName = lncfg.SqliteChainDBName
546+
547+
case lncfg.NSNeutrinoDB:
548+
dbName = lncfg.SqliteNeutrinoDBName
549+
}
550+
551+
args = []interface{}{
552+
context.Background(),
553+
&sqlite.Config{
554+
Timeout: time.Minute,
555+
},
556+
path,
557+
dbName,
558+
prefix,
559+
}
560+
561+
log("Opening sqlite backend with prefix '%s'", prefix)
562+
453563
default:
454564
return nil, fmt.Errorf("unknown backend: %v", backend)
455565
}
@@ -548,7 +658,7 @@ func addMarker(db walletdb.DB, markerKey []byte) error {
548658
return rwtx.Commit()
549659
}
550660

551-
func checkMigrationsApplied(db walletdb.DB) error {
661+
func checkChannelDBMigrationsApplied(db walletdb.DB) error {
552662
var meta channeldb.Meta
553663
err := kvdb.View(db, func(tx kvdb.RTx) error {
554664
return channeldb.FetchMeta(&meta, tx)

0 commit comments

Comments
 (0)