Skip to content

Commit 67088f2

Browse files
committed
migratedb: add sqlite possibility
1 parent 7c12213 commit 67088f2

File tree

1 file changed

+150
-34
lines changed

1 file changed

+150
-34
lines changed

cmd_migrate_db.go

+150-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."`
63+
}
64+
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
5179
}
5280

53-
func (d *DB) isRemote() bool {
54-
return d.Backend == lncfg.EtcdBackend ||
55-
d.Backend == lncfg.PostgresBackend
81+
// isBoltDB returns true if the db is a type bolt db.
82+
func (db *DB) isBoltDB() bool {
83+
return db.Backend == lncfg.BoltBackend
5684
}
5785

58-
func (d *DB) isEtcd() bool {
59-
return d.Backend == lncfg.EtcdBackend
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
@@ -242,6 +289,9 @@ func (x *migrateDBCommand) Execute(_ []string) error {
242289
if err := addMarker(destDb, alreadyMigratedKey); err != nil {
243290
return err
244291
}
292+
293+
log("Migration of DB with prefix %s completed successfully",
294+
prefix)
245295
}
246296

247297
return nil
@@ -286,7 +336,9 @@ func (x *migrateDBCommand) migrateKvdb(srcTx walletdb.ReadWriteTx,
286336
}
287337

288338
// Migrate wallet created marker.
289-
if prefix == lncfg.NSWalletDB && x.Dest.isRemote() {
339+
//
340+
// TODO(ziggie): Why not for bbolt backends ?
341+
if prefix == lncfg.NSWalletDB && !x.Dest.isBoltDB() {
290342
const (
291343
walletMetaBucket = "lnwallet"
292344
walletReadyKey = "ready"
@@ -382,21 +434,30 @@ func (x *migrateDBCommand) migrateEtcd(srcTx walletdb.ReadWriteTx,
382434
return nil
383435
}
384436

385-
func openDb(cfg *DB, prefix string) (walletdb.DB, error) {
437+
func openDb(cfg *DB, prefix, network string) (walletdb.DB, error) {
386438
backend := cfg.Backend
387439

388-
var args []interface{}
440+
// Init the db connections for sql backends.
441+
err := cfg.Init()
442+
if err != nil {
443+
return nil, err
444+
}
389445

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-
)
446+
// Settings to open a particular db backend.
447+
var args []interface{}
397448

398449
switch backend {
399450
case lncfg.BoltBackend:
451+
// Directories where the db files are located.
452+
graphDir := filepath.Join(cfg.Bolt.DataDir, "graph", network)
453+
walletDir := filepath.Join(
454+
cfg.Bolt.DataDir, "chain", "bitcoin", network,
455+
)
456+
towerServerDir := filepath.Join(
457+
cfg.Bolt.TowerDir, "bitcoin", network,
458+
)
459+
460+
// Path to the db file.
400461
var path string
401462
switch prefix {
402463
case lncfg.NSChannelDB:
@@ -443,13 +504,68 @@ func openDb(cfg *DB, prefix string) (walletdb.DB, error) {
443504
args = []interface{}{
444505
context.Background(),
445506
&postgres.Config{
446-
Dsn: cfg.Postgres.Dsn,
507+
Dsn: cfg.Postgres.Dsn,
508+
Timeout: time.Minute,
509+
MaxConnections: 10,
447510
},
448511
prefix,
449512
}
513+
450514
log("Opening postgres backend at %s with prefix '%s'",
451515
cfg.Postgres.Dsn, prefix)
452516

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

551-
func checkMigrationsApplied(db walletdb.DB) error {
667+
func checkChannelDBMigrationsApplied(db walletdb.DB) error {
552668
var meta channeldb.Meta
553669
err := kvdb.View(db, func(tx kvdb.RTx) error {
554670
return channeldb.FetchMeta(&meta, tx)

0 commit comments

Comments
 (0)