@@ -177,6 +177,14 @@ var (
177177 lncfg .NSWalletDB ,
178178 lncfg .NSNeutrinoDB ,
179179 }
180+
181+ // databasesWithMigrations are the databases that have new versions
182+ // introduced during their lifetime and therefore need to be up to
183+ // date before we can start the migration to SQL backends.
184+ databasesWithMigrations = []string {
185+ lncfg .NSChannelDB ,
186+ lncfg .NSTowerClientDB ,
187+ }
180188)
181189
182190func (x * migrateDBCommand ) Execute (_ []string ) error {
@@ -205,6 +213,60 @@ func (x *migrateDBCommand) Execute(_ []string) error {
205213 // interceptor.
206214 ctx := getContext ()
207215
216+ // Before starting any migration, make sure that all existing dbs have
217+ // the latest migrations applied so that we do only migrate when all
218+ // dbs are up to date. For example it might happen that a user run a
219+ // watchtower client earlier and has it switched off since new
220+ // migrations have been introduced. In that case we do not start the
221+ // migration but first let the user either delete the outdated db or
222+ // migrate it by activating the watchtower client again.
223+ for _ , prefix := range databasesWithMigrations {
224+ logger .Infof ("Checking db version of database %s" , prefix )
225+
226+ // Check if the database file exists before trying to open it.
227+ dbPath := getBoltDBPath (x .Source , prefix , x .Network )
228+ if dbPath == "" {
229+ return fmt .Errorf ("unknown prefix: %s" , prefix )
230+ }
231+
232+ // Open and check the database version.
233+ srcDb , err := openSourceDb (x .Source , prefix , x .Network , true )
234+ if err == kvdb .ErrDbDoesNotExist {
235+ // Only skip if it's an optional because it's not
236+ // required to run a wtclient or wtserver for example.
237+ if optionalDBs [prefix ] {
238+ logger .Warnf ("Skipping checking db version " +
239+ "of optional DB %s: not found" , prefix )
240+
241+ continue
242+ }
243+ }
244+ if err != nil {
245+ return fmt .Errorf ("failed to open source db with " +
246+ "prefix `%s` for version check: %w" , prefix ,
247+ err )
248+ }
249+
250+ switch prefix {
251+ case lncfg .NSChannelDB :
252+ err := checkChannelDBMigrationsApplied (srcDb )
253+ if err != nil {
254+ srcDb .Close ()
255+ return err
256+ }
257+
258+ case lncfg .NSTowerClientDB :
259+ err := checkWTClientDBMigrationsApplied (srcDb )
260+ if err != nil {
261+ srcDb .Close ()
262+ return err
263+ }
264+ }
265+
266+ srcDb .Close ()
267+ logger .Infof ("Version check passed for database %s" , prefix )
268+ }
269+
208270 for _ , prefix := range allDBPrefixes {
209271 logger .Infof ("Attempting to migrate DB with prefix `%s`" , prefix )
210272
@@ -344,31 +406,6 @@ func (x *migrateDBCommand) Execute(_ []string) error {
344406 prefix , sourceMarker , destMarker )
345407 }
346408
347- // Check that the source DB has had all its schema migrations
348- // applied before we migrate any of its data. Currently only
349- // migration of the channel.db and the watchtower.db exist.
350- // Check channel.db migrations.
351- if prefix == lncfg .NSChannelDB {
352- logger .Info ("Checking DB version of source DB " +
353- "(channel.db)" )
354-
355- err := checkChannelDBMigrationsApplied (srcDb )
356- if err != nil {
357- return err
358- }
359- }
360-
361- // Check watchtower client DB migrations.
362- if prefix == lncfg .NSTowerClientDB {
363- logger .Info ("Checking DB version of source DB " +
364- "(wtclient.db)" )
365-
366- err := checkWTClientDBMigrationsApplied (srcDb )
367- if err != nil {
368- return err
369- }
370- }
371-
372409 // In case we want to start a new migration we delete the
373410 // migration meta db if it exits. This can only be done if
374411 // the db is not already successfully migrated otherwise
@@ -826,7 +863,9 @@ func checkWTClientDBMigrationsApplied(db kvdb.Backend) error {
826863 return fmt .Errorf ("refusing to migrate source database with " +
827864 "version %d while latest known DB version is %d; " +
828865 "please upgrade the DB before using the data " +
829- "migration tool" , version , wtdb .LatestDBMigrationVersion ())
866+ "migration tool or delete the wtclient.db manually " +
867+ "in case you don't plan to use the watchtower client " +
868+ "anymore" , version , wtdb .LatestDBMigrationVersion ())
830869 }
831870
832871 return nil
0 commit comments