From a2abcd07d8d272b8fddf2b24809f6bbfb1e35efa Mon Sep 17 00:00:00 2001 From: sputn1ck Date: Fri, 19 May 2023 15:09:08 +0200 Subject: [PATCH] loopd: Run migration if boltdb exists --- loopd/daemon.go | 20 ++++++++-- loopd/migration.go | 92 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 loopd/migration.go diff --git a/loopd/daemon.go b/loopd/daemon.go index 787afd2..25c4a9d 100644 --- a/loopd/daemon.go +++ b/loopd/daemon.go @@ -370,8 +370,24 @@ func (d *Daemon) initialize(withMacaroonService bool) error { } } + // Both the client RPC server and and the swap server client should + // stop on main context cancel. So we create it early and pass it down. + d.mainCtx, d.mainCtxCancel = context.WithCancel(context.Background()) + log.Infof("Swap server address: %v", d.cfg.Server.Host) + // Check if we need to migrate the database. + if needSqlMigration(d.cfg) { + log.Infof("Boltdb found, running migration") + + err := migrateBoltdb(d.mainCtx, d.cfg) + if err != nil { + return fmt.Errorf("unable to migrate boltdb: %v", err) + } + + log.Infof("Successfully migrated boltdb") + } + // Create an instance of the loop client library. swapclient, clientCleanup, err := getClient(d.cfg, &d.lnd.LndServices) if err != nil { @@ -379,10 +395,6 @@ func (d *Daemon) initialize(withMacaroonService bool) error { } d.clientCleanup = clientCleanup - // Both the client RPC server and and the swap server client should - // stop on main context cancel. So we create it early and pass it down. - d.mainCtx, d.mainCtxCancel = context.WithCancel(context.Background()) - // Add our debug permissions to our main set of required permissions // if compiled in. for endpoint, perm := range debugRequiredPermissions { diff --git a/loopd/migration.go b/loopd/migration.go new file mode 100644 index 0000000..cc9b369 --- /dev/null +++ b/loopd/migration.go @@ -0,0 +1,92 @@ +package loopd + +import ( + "context" + "fmt" + "os" + "path/filepath" + + "github.com/lightninglabs/lndclient" + "github.com/lightninglabs/loop/loopdb" + "github.com/lightningnetwork/lnd/lnrpc" +) + +// migrateBoltdb migrates the boltdb to sqlite. +func migrateBoltdb(ctx context.Context, cfg *Config) error { + // First get the chain params. + chainParams, err := lndclient.Network(cfg.Network).ChainParams() + if err != nil { + return err + } + + // First open the bolt db. + boltdb, err := loopdb.NewBoltSwapStore(cfg.DataDir, chainParams) + if err != nil { + return err + } + defer boltdb.Close() + + var db loopdb.SwapStore + switch cfg.DatabaseBackend { + case DatabaseBackendSqlite: + log.Infof("Opening sqlite3 database at: %v", + cfg.Sqlite.DatabaseFileName) + db, err = loopdb.NewSqliteStore( + cfg.Sqlite, chainParams, + ) + + case DatabaseBackendPostgres: + log.Infof("Opening postgres database at: %v", + cfg.Postgres.DSN(true)) + db, err = loopdb.NewPostgresStore( + cfg.Postgres, chainParams, + ) + + default: + return fmt.Errorf("unknown database backend: %s", + cfg.DatabaseBackend) + } + if err != nil { + return fmt.Errorf("unable to open database: %v", err) + } + + defer db.Close() + + // Create a new migrator manager. + migrator := loopdb.NewMigratorManager(boltdb, db) + + // Run the migration. + err = migrator.RunMigrations(ctx) + if err != nil { + return err + } + + // If the migration was successfull we'll rename the bolt db to + // loop.db.bk. + err = os.Rename( + filepath.Join(cfg.DataDir, "loop.db"), + filepath.Join(cfg.DataDir, "loop.db.bk"), + ) + if err != nil { + return err + } + + return nil +} + +// needSqlMigration checks if the boltdb exists at it's default location +// and returns true if it does. +func needSqlMigration(cfg *Config) bool { + // First check if the data directory exists. + if !lnrpc.FileExists(cfg.DataDir) { + return false + } + + // Now we'll check if the bolt db exists. + if !lnrpc.FileExists(filepath.Join(cfg.DataDir, "loop.db")) { + return false + } + + // If both the folder and the bolt db exist, we'll return true. + return true +}