From 5c402472a4666db88f32d4d7d35da247e8bee114 Mon Sep 17 00:00:00 2001 From: ziggie Date: Thu, 3 Apr 2025 03:06:43 +0200 Subject: [PATCH 1/2] mulit: move neutrino.db also to postgres --- config_builder.go | 88 ++++++++++++++++++++++++++++++++++++++++++++++- lncfg/db.go | 1 + 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/config_builder.go b/config_builder.go index 8db209393..2214250e7 100644 --- a/config_builder.go +++ b/config_builder.go @@ -1430,6 +1430,74 @@ func importWatchOnlyAccounts(wallet *wallet.Wallet, return nil } +// handleNeutrinoPostgresDBMigration handles the migration of the neutrino db +// to postgres. Initially we kept the neutrino db in the bolt db when running +// with kvdb postgres backend. Now now move it to postgres as well. However we +// need to make a distinction whether the user migrated the neutrino db to +// postgres via lndinit or not. Currently if the db is not migrated we start +// with a fresh db in postgres. +// +// TODO(ziggie): Also migrate the db to postgres in case it is still not +// migrated ? +func handleNeutrinoPostgresDBMigration(dbName, dbPath string, + cfg *Config) error { + + if !lnrpc.FileExists(dbName) { + return nil + } + + // Open bolt db to check if it is tombstoned. If it is we assume that + // the neutrino db was successfully migrated to postgres. We open it + // in read-only mode to avoid long db open times. + boltDB, err := kvdb.Open( + kvdb.BoltBackendName, dbName, true, + cfg.DB.Bolt.DBTimeout, true, + ) + if err != nil { + return fmt.Errorf("failed to open bolt db: %w", err) + } + defer boltDB.Close() + + isTombstoned := false + err = boltDB.View(func(tx kvdb.RTx) error { + _, err = channeldb.CheckMarkerPresent( + tx, channeldb.TombstoneKey, + ) + + return err + }, func() {}) + if err == nil { + isTombstoned = true + } + + if isTombstoned { + ltndLog.Infof("Neutrino Bolt DB is tombstoned, assuming " + + "database was successfully migrated to postgres") + + return nil + } + + // If the db is not tombstoned, we remove the files and start fresh with + // postgres. This is the case when a user was running lnd with the + // postgres backend from the beginning without migrating from bolt. + ltndLog.Infof("Neutrino Bolt DB found but NOT tombstoned, removing " + + "it and starting fresh with postgres") + + filesToRemove := []string{ + filepath.Join(dbPath, "block_headers.bin"), + filepath.Join(dbPath, "reg_filter_headers.bin"), + dbName, + } + + for _, file := range filesToRemove { + if err := os.Remove(file); err != nil { + ltndLog.Warnf("Could not remove %s: %v", file, err) + } + } + + return nil +} + // initNeutrinoBackend inits a new instance of the neutrino light client // backend given a target chain directory to store the chain state. func initNeutrinoBackend(ctx context.Context, cfg *Config, chainDir string, @@ -1471,8 +1539,26 @@ func initNeutrinoBackend(ctx context.Context, cfg *Config, chainDir string, lncfg.SqliteNeutrinoDBName, lncfg.NSNeutrinoDB, ) + case cfg.DB.Backend == kvdb.PostgresBackendName: + dbName := filepath.Join(dbPath, lncfg.NeutrinoDBName) + + // This code needs to be in place because we did not start + // the postgres backend for neutrino at the beginning. Now we + // are also moving it into the postgres backend so we can phase + // out the bolt backend. + err = handleNeutrinoPostgresDBMigration(dbName, dbPath, cfg) + if err != nil { + return nil, nil, err + } + + postgresConfig := lncfg.GetPostgresConfigKVDB(cfg.DB.Postgres) + db, err = kvdb.Open( + kvdb.PostgresBackendName, ctx, postgresConfig, + lncfg.NSNeutrinoDB, + ) + default: - dbName := filepath.Join(dbPath, "neutrino.db") + dbName := filepath.Join(dbPath, lncfg.NeutrinoDBName) db, err = walletdb.Create( kvdb.BoltBackendName, dbName, !cfg.SyncFreelist, cfg.DB.Bolt.DBTimeout, false, diff --git a/lncfg/db.go b/lncfg/db.go index d6400eac5..553fa5733 100644 --- a/lncfg/db.go +++ b/lncfg/db.go @@ -25,6 +25,7 @@ const ( TowerClientDBName = "wtclient.db" TowerServerDBName = "watchtower.db" WalletDBName = "wallet.db" + NeutrinoDBName = "neutrino.db" SqliteChannelDBName = "channel.sqlite" SqliteChainDBName = "chain.sqlite" From 417d2de43ecbd33f34904fd43592ff986254cddb Mon Sep 17 00:00:00 2001 From: ziggie Date: Mon, 7 Apr 2025 19:11:54 +0200 Subject: [PATCH 2/2] docs: add release-notes --- docs/release-notes/release-notes-0.19.0.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/release-notes/release-notes-0.19.0.md b/docs/release-notes/release-notes-0.19.0.md index 0228d234d..5f02bbbd8 100644 --- a/docs/release-notes/release-notes-0.19.0.md +++ b/docs/release-notes/release-notes-0.19.0.md @@ -150,8 +150,6 @@ close transaction. initial historical sync may be blocked due to a race condition in handling the syncer's internal state. - - * [The max fee rate](https://github.com/lightningnetwork/lnd/pull/9491) is now respected when a coop close is initiated. Before the max fee rate would only be effective for the remote party in the negotiation. @@ -466,6 +464,9 @@ the on going rate we'll permit. * [Establish a base DB version even if it is not yet tracked](https://github.com/lightningnetwork/lnd/pull/9647). +* [When running with neutrino as a backend with the kv-db backend `postgres` +selected use postgres for the neutrino.db store](https://github.com/lightningnetwork/lnd/pull/9674). + ## Code Health * A code refactor that [moves all the graph related DB code out of the