diff --git a/Makefile b/Makefile index 44855b5..143817f 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,9 @@ DOCKER_TOOLS = docker run \ TEST_FLAGS = -test.timeout=20m +DEV_TAGS = kvdb_postgres kvdb_sqlite + + UNIT := $(GOLIST) | $(XARGS) env $(GOTEST) $(TEST_FLAGS) LDFLAGS := -X main.Commit=$(shell git describe --tags) RELEASE_LDFLAGS := -s -w -buildid= $(LDFLAGS) @@ -70,7 +73,7 @@ build: install: @$(call print, "Installing chantools.") - $(GOINSTALL) -ldflags "$(LDFLAGS)" ./... + $(GOINSTALL) -tags="$(DEV_TAGS)" -ldflags "$(LDFLAGS)" ./... release: @$(call print, "Creating release of chantools.") diff --git a/cmd/chantools/chanbackup.go b/cmd/chantools/chanbackup.go index 2cfb980..6234847 100644 --- a/cmd/chantools/chanbackup.go +++ b/cmd/chantools/chanbackup.go @@ -55,10 +55,13 @@ func (c *chanBackupCommand) Execute(_ *cobra.Command, _ []string) error { } // Check that we have a channel DB. - if c.ChannelDB == "" { - return errors.New("channel DB is required") - } - db, err := lnd.OpenDB(c.ChannelDB, true) + // if c.ChannelDB == "" { + // return errors.New("channel DB is required") + // } + + dbConfig := GetDBConfig() + + db, err := lnd.OpenChannelDB(dbConfig, chainParams.Name) if err != nil { return fmt.Errorf("error opening rescue DB: %w", err) } diff --git a/cmd/chantools/deletepayments.go b/cmd/chantools/deletepayments.go index 17b4275..4870fde 100644 --- a/cmd/chantools/deletepayments.go +++ b/cmd/chantools/deletepayments.go @@ -1,7 +1,6 @@ package main import ( - "errors" "fmt" "github.com/lightninglabs/chantools/lnd" @@ -45,10 +44,12 @@ run lnd ` + lndVersion + ` or later after using this command!'`, func (c *deletePaymentsCommand) Execute(_ *cobra.Command, _ []string) error { // Check that we have a channel DB. - if c.ChannelDB == "" { - return errors.New("channel DB is required") - } - db, err := lnd.OpenDB(c.ChannelDB, false) + // if c.ChannelDB == "" { + // return errors.New("channel DB is required") + // } + dbConfig := GetDBConfig() + + db, err := lnd.OpenChannelDB(dbConfig, chainParams.Name) if err != nil { return fmt.Errorf("error opening rescue DB: %w", err) } diff --git a/cmd/chantools/dropchannelgraph.go b/cmd/chantools/dropchannelgraph.go index d7f2b8d..b2fba9e 100644 --- a/cmd/chantools/dropchannelgraph.go +++ b/cmd/chantools/dropchannelgraph.go @@ -82,10 +82,13 @@ chantools dropchannelgraph \ func (c *dropChannelGraphCommand) Execute(_ *cobra.Command, _ []string) error { // Check that we have a channel DB. - if c.ChannelDB == "" { - return errors.New("channel DB is required") - } - db, err := lnd.OpenDB(c.ChannelDB, false) + // if c.ChannelDB == "" { + // return errors.New("channel DB is required") + // } + + dbConfig := GetDBConfig() + + db, err := lnd.OpenChannelDB(dbConfig, chainParams.Name) if err != nil { return fmt.Errorf("error opening rescue DB: %w", err) } diff --git a/cmd/chantools/dropgraphzombies.go b/cmd/chantools/dropgraphzombies.go index 7daf893..9aea120 100644 --- a/cmd/chantools/dropgraphzombies.go +++ b/cmd/chantools/dropgraphzombies.go @@ -1,7 +1,6 @@ package main import ( - "errors" "fmt" "github.com/lightninglabs/chantools/lnd" @@ -52,10 +51,12 @@ run lnd ` + lndVersion + ` or later after using this command!'`, func (c *dropGraphZombiesCommand) Execute(_ *cobra.Command, _ []string) error { // Check that we have a channel DB. - if c.ChannelDB == "" { - return errors.New("channel DB is required") - } - db, err := lnd.OpenDB(c.ChannelDB, false) + // if c.ChannelDB == "" { + // return errors.New("channel DB is required") + // } + dbConfig := GetDBConfig() + + db, err := lnd.OpenChannelDB(dbConfig, chainParams.Name) if err != nil { return fmt.Errorf("error opening rescue DB: %w", err) } diff --git a/cmd/chantools/dumpchannels.go b/cmd/chantools/dumpchannels.go index f7b59ed..c48a1a8 100644 --- a/cmd/chantools/dumpchannels.go +++ b/cmd/chantools/dumpchannels.go @@ -54,10 +54,12 @@ given lnd channel.db gile in a human readable format.`, func (c *dumpChannelsCommand) Execute(_ *cobra.Command, _ []string) error { // Check that we have a channel DB. - if c.ChannelDB == "" { - return errors.New("channel DB is required") - } - db, err := lnd.OpenDB(c.ChannelDB, true) + // if c.ChannelDB == "" { + // return errors.New("channel DB is required") + // } + dbConfig := GetDBConfig() + + db, err := lnd.OpenChannelDB(dbConfig, chainParams.Name) if err != nil { return fmt.Errorf("error opening rescue DB: %w", err) } diff --git a/cmd/chantools/forceclose.go b/cmd/chantools/forceclose.go index 9e4cc57..894c5ee 100644 --- a/cmd/chantools/forceclose.go +++ b/cmd/chantools/forceclose.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/hex" "encoding/json" - "errors" "fmt" "io" "os" @@ -79,10 +78,12 @@ func (c *forceCloseCommand) Execute(_ *cobra.Command, _ []string) error { } // Check that we have a channel DB. - if c.ChannelDB == "" { - return errors.New("rescue DB is required") - } - db, err := lnd.OpenDB(c.ChannelDB, true) + // if c.ChannelDB == "" { + // return errors.New("rescue DB is required") + // } + dbConfig := GetDBConfig() + + db, err := lnd.OpenChannelDB(dbConfig, chainParams.Name) if err != nil { return fmt.Errorf("error opening rescue DB: %w", err) } diff --git a/cmd/chantools/migratedb.go b/cmd/chantools/migratedb.go index 6ef9880..f561717 100644 --- a/cmd/chantools/migratedb.go +++ b/cmd/chantools/migratedb.go @@ -1,7 +1,6 @@ package main import ( - "errors" "fmt" "github.com/lightninglabs/chantools/lnd" @@ -41,12 +40,14 @@ run lnd ` + lndVersion + ` or later after using this command!'`, func (c *migrateDBCommand) Execute(_ *cobra.Command, _ []string) error { // Check that we have a channel DB. - if c.ChannelDB == "" { - return errors.New("channel DB is required") - } - db, err := lnd.OpenDB(c.ChannelDB, false) + // if c.ChannelDB == "" { + // return errors.New("channel DB is required") + // } + dbConfig := GetDBConfig() + + db, err := lnd.OpenChannelDB(dbConfig, chainParams.Name) if err != nil { - return fmt.Errorf("error opening DB: %w", err) + return fmt.Errorf("error opening rescue DB: %w", err) } return db.Close() diff --git a/cmd/chantools/removechannel.go b/cmd/chantools/removechannel.go index 15697ff..e037746 100644 --- a/cmd/chantools/removechannel.go +++ b/cmd/chantools/removechannel.go @@ -1,7 +1,6 @@ package main import ( - "errors" "fmt" "strconv" "strings" @@ -53,12 +52,14 @@ run lnd ` + lndVersion + ` or later after using this command!`, func (c *removeChannelCommand) Execute(_ *cobra.Command, _ []string) error { // Check that we have a channel DB. - if c.ChannelDB == "" { - return errors.New("channel DB is required") - } - db, err := lnd.OpenDB(c.ChannelDB, false) + // if c.ChannelDB == "" { + // return errors.New("channel DB is required") + // } + dbConfig := GetDBConfig() + + db, err := lnd.OpenChannelDB(dbConfig, chainParams.Name) if err != nil { - return fmt.Errorf("error opening channel DB: %w", err) + return fmt.Errorf("error opening rescue DB: %w", err) } defer func() { if err := db.Close(); err != nil { diff --git a/cmd/chantools/rescueclosed.go b/cmd/chantools/rescueclosed.go index 9e9dd94..0b43b6a 100644 --- a/cmd/chantools/rescueclosed.go +++ b/cmd/chantools/rescueclosed.go @@ -125,8 +125,11 @@ func (c *rescueClosedCommand) Execute(_ *cobra.Command, _ []string) error { // What way of recovery has the user chosen? From summary and DB or from // address and commit point? switch { + // Needs an update we don't use the string anymore case c.ChannelDB != "": - db, err := lnd.OpenDB(c.ChannelDB, true) + dbConfig := GetDBConfig() + + db, err := lnd.OpenChannelDB(dbConfig, chainParams.Name) if err != nil { return fmt.Errorf("error opening rescue DB: %w", err) } diff --git a/cmd/chantools/rescuefunding.go b/cmd/chantools/rescuefunding.go index bb89f38..db8fcd3 100644 --- a/cmd/chantools/rescuefunding.go +++ b/cmd/chantools/rescuefunding.go @@ -158,7 +158,9 @@ func (c *rescueFundingCommand) Execute(_ *cobra.Command, _ []string) error { "channel point or both local and remote pubkey") case c.ChannelDB != "" && c.DBChannelPoint != "": - db, err := lnd.OpenDB(c.ChannelDB, true) + dbConfig := GetDBConfig() + + db, err := lnd.OpenChannelDB(dbConfig, chainParams.Name) if err != nil { return fmt.Errorf("error opening rescue DB: %w", err) } diff --git a/cmd/chantools/root.go b/cmd/chantools/root.go index b712c2e..8e19701 100644 --- a/cmd/chantools/root.go +++ b/cmd/chantools/root.go @@ -10,6 +10,7 @@ import ( "strings" "time" + "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/btcutil/hdkeychain" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btclog" @@ -19,7 +20,10 @@ import ( "github.com/lightningnetwork/lnd/build" "github.com/lightningnetwork/lnd/chanbackup" "github.com/lightningnetwork/lnd/channeldb" + "github.com/lightningnetwork/lnd/kvdb/postgres" + "github.com/lightningnetwork/lnd/kvdb/sqlite" "github.com/lightningnetwork/lnd/peer" + "github.com/ory/viper" "github.com/spf13/cobra" ) @@ -50,6 +54,8 @@ var ( logWriter = build.NewRotatingLogWriter() log = build.NewSubLogger("CHAN", genSubLogger(logWriter)) chainParams = &chaincfg.MainNetParams + // defaultDataDir is the default data directory for lnd. + defaultDataDir = btcutil.AppDataDir("lnd", false) ) var rootCmd = &cobra.Command{ @@ -96,6 +102,24 @@ func main() { &Signet, "signet", "s", false, "Indicates if the public "+ "signet parameters should be used", ) + rootCmd.PersistentFlags().String("db.backend", "bolt", "The selected database backend (bolt/etcd/postgres/sqlite)") + + // Bolt settings + rootCmd.PersistentFlags().Duration("db.bolt.dbtimeout", 10*time.Second, "Specify the timeout value used when opening the database") + rootCmd.PersistentFlags().String("db.bolt.data-dir", defaultDataDir, "Lnd data dir where bolt dbs are located") + rootCmd.PersistentFlags().String("db.bolt.tower-dir", defaultDataDir, "Lnd watchtower dir where bolt dbs are located") + + // Sqlite settings + rootCmd.PersistentFlags().String("db.sqlite.data-dir", defaultDataDir, "Lnd data dir where sqlite dbs are located") + rootCmd.PersistentFlags().String("db.sqlite.tower-dir", defaultDataDir, "Lnd watchtower dir where sqlite dbs are located") + rootCmd.PersistentFlags().Duration("db.sqlite.timeout", 10*time.Second, "Specify the timeout value used when opening the database") + + // Postgres settings + rootCmd.PersistentFlags().String("db.postgres.dsn", "", "Postgres connection string") + rootCmd.PersistentFlags().Duration("db.postgres.timeout", 10*time.Second, "Specify the timeout value used when opening the database") + + // Bind flags to viper + viper.BindPFlags(rootCmd.PersistentFlags()) rootCmd.AddCommand( newChanBackupCommand(), @@ -275,10 +299,11 @@ func (f *inputFlags) parseInputType() ([]*dataformat.SummaryEntry, error) { target = &dataformat.SummaryEntryFile{} case f.FromChannelDB != "": - db, err := lnd.OpenDB(f.FromChannelDB, true) + dbConfig := GetDBConfig() + + db, err := lnd.OpenChannelDB(dbConfig, chainParams.Name) if err != nil { - return nil, fmt.Errorf("error opening channel DB: %w", - err) + return nil, fmt.Errorf("error opening rescue DB: %w", err) } target = &dataformat.ChannelDBFile{DB: db.ChannelStateDB()} return target.AsSummaryEntries() @@ -365,3 +390,28 @@ func newExplorerAPI(apiURL string) *btc.ExplorerAPI { // Otherwise use the provided URL. return &btc.ExplorerAPI{BaseURL: apiURL} } + +// GetDBConfig returns the database configuration from viper/cobra flags +func GetDBConfig() lnd.DB { + return lnd.DB{ + Backend: viper.GetString("db.backend"), + Bolt: &lnd.Bolt{ + DBTimeout: viper.GetDuration("db.bolt.dbtimeout"), + DataDir: viper.GetString("db.bolt.data-dir"), + TowerDir: viper.GetString("db.bolt.tower-dir"), + }, + Sqlite: &lnd.Sqlite{ + DataDir: viper.GetString("db.sqlite.data-dir"), + TowerDir: viper.GetString("db.sqlite.tower-dir"), + Config: &sqlite.Config{ + MaxConnections: viper.GetInt("db.sqlite.timeout"), + }, + }, + Postgres: &postgres.Config{ + Dsn: viper.GetString("db.postgres.dsn"), + MaxConnections: viper.GetInt("db.postgres.max-connections"), + Timeout: viper.GetDuration("db.postgres.timeout"), + }, + // Add Etcd config if needed + } +} diff --git a/go.mod b/go.mod index 379ccb1..d93ac76 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,10 @@ require ( golang.org/x/oauth2 v0.14.0 ) -require github.com/tv42/zbase32 v0.0.0-20220222190657-f76a9fc892fa +require ( + github.com/ory/viper v1.7.5 + github.com/tv42/zbase32 v0.0.0-20220222190657-f76a9fc892fa +) require ( github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect @@ -53,6 +56,7 @@ require ( github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 // indirect github.com/btcsuite/winsvc v1.0.0 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/containerd/continuity v0.3.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect @@ -60,6 +64,7 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect github.com/decred/dcrd/lru v1.1.2 // indirect + github.com/dgraph-io/ristretto v0.0.1 // indirect github.com/docker/cli v20.10.17+incompatible // indirect github.com/docker/docker v24.0.9+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect @@ -68,6 +73,7 @@ require ( github.com/fergusstrange/embedded-postgres v1.25.0 // indirect github.com/fortytw2/leaktest v1.3.0 // indirect github.com/frankban/quicktest v1.14.3 // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/go-errors/errors v1.0.1 // indirect github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -86,6 +92,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect @@ -121,6 +128,7 @@ require ( github.com/lightningnetwork/lnd/sqldb v1.0.4 // indirect github.com/lightningnetwork/lnd/tlv v1.2.6 // indirect github.com/ltcsuite/ltcd v0.0.0-20191228044241-92166e412499 // indirect + github.com/magiconair/properties v1.8.1 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/miekg/dns v1.1.43 // indirect @@ -133,6 +141,7 @@ require ( github.com/opencontainers/image-spec v1.0.2 // indirect github.com/opencontainers/runc v1.1.14 // indirect github.com/ory/dockertest/v3 v3.10.0 // indirect + github.com/pelletier/go-toml v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.11.1 // indirect @@ -146,8 +155,12 @@ require ( github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sirupsen/logrus v1.9.2 // indirect github.com/soheilhy/cmux v0.1.5 // indirect + github.com/spf13/afero v1.9.2 // indirect + github.com/spf13/cast v1.3.0 // indirect + github.com/spf13/jwalterweatherman v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.2 // indirect + github.com/subosito/gotenv v1.2.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect @@ -193,6 +206,7 @@ require ( google.golang.org/grpc v1.59.0 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/errgo.v1 v1.0.1 // indirect + gopkg.in/ini.v1 v1.51.0 // indirect gopkg.in/macaroon-bakery.v2 v2.1.0 // indirect gopkg.in/macaroon.v2 v2.1.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect diff --git a/go.sum b/go.sum index cb50828..91e9620 100644 --- a/go.sum +++ b/go.sum @@ -613,6 +613,7 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw= github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344 h1:cDVUiFo+npB0ZASqnw4q90ylaVAbnYyx0JYqK4YcGok= github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344/go.mod h1:9pIqrY6SXNL8vjRQE5Hd/OL5GyK/9MrGUWs87z/eFfk= @@ -695,6 +696,7 @@ github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 h1:uH66TXeswKn5PW5zdZ39xEwfS9an067BirqA+P4QaLI= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -758,7 +760,11 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3 github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/decred/dcrd/lru v1.1.2 h1:KdCzlkxppuoIDGEvCGah1fZRicrDH36IipvlB1ROkFY= github.com/decred/dcrd/lru v1.1.2/go.mod h1:gEdCVgXs1/YoBvFWt7Scgknbhwik3FgVSzlnCcXL2N8= +github.com/dgraph-io/ristretto v0.0.1 h1:cJwdnj42uV8Jg4+KLrYovLiCgIfz9wtWm6E6KA+1tLs= +github.com/dgraph-io/ristretto v0.0.1/go.mod h1:T40EBc7CJke8TkpiYfGGKAeFjSaxuFXhuXRyumBd6RE= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dhui/dktest v0.4.0 h1:z05UmuXZHO/bgj/ds2bGMBu8FI4WA+Ag/m3ghL+om7M= github.com/dhui/dktest v0.4.0/go.mod h1:v/Dbz1LgCBOi2Uki2nUqLBGa83hWBGFMu5MrgMDCc78= @@ -982,6 +988,7 @@ github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57Q github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -1025,6 +1032,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= @@ -1110,6 +1118,7 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= github.com/juju/clock v0.0.0-20220203021603-d9deb868a28a h1:Az/6CM/P5guGHNy7r6TkOCctv3lDmN3W1uhku7QMupk= @@ -1153,6 +1162,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -1217,6 +1227,7 @@ github.com/lunixbochs/vtclean v0.0.0-20160125035106-4fbf7632a2c6/go.mod h1:pHhQN github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.6/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -1290,7 +1301,10 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4= github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg= +github.com/ory/viper v1.7.5 h1:+xVdq7SU3e1vNaCsk/ixsfxE4zylk1TJUiJrY647jUE= +github.com/ory/viper v1.7.5/go.mod h1:ypOuyJmEUb3oENywQZRgeAMwqgOyDqwboO1tj3DjTaM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY= github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI= @@ -1367,19 +1381,25 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y= github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -1404,6 +1424,7 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= @@ -1523,6 +1544,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= @@ -1746,6 +1768,7 @@ golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2205,6 +2228,7 @@ gopkg.in/errgo.v1 v1.0.1/go.mod h1:3NjfXwocQRYAPTq4/fzX+CwUhPRcR/azYRhj8G+LqMo= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/macaroon-bakery.v2 v2.1.0 h1:9Jw/+9XHBSutkaeVpWhDx38IcSNLJwWUICkOK98DHls= gopkg.in/macaroon-bakery.v2 v2.1.0/go.mod h1:B4/T17l+ZWGwxFSZQmlBwp25x+og7OkhETfr3S9MbIA= diff --git a/lnd/channeldb.go b/lnd/channeldb.go index b83758f..9fc0a11 100644 --- a/lnd/channeldb.go +++ b/lnd/channeldb.go @@ -1,36 +1,216 @@ package lnd import ( + "context" "errors" "fmt" "io" "os" + "path/filepath" "time" "github.com/btcsuite/btcwallet/walletdb" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/kvdb" + "github.com/lightningnetwork/lnd/kvdb/etcd" + "github.com/lightningnetwork/lnd/kvdb/postgres" + "github.com/lightningnetwork/lnd/kvdb/sqlbase" + "github.com/lightningnetwork/lnd/kvdb/sqlite" + "github.com/lightningnetwork/lnd/lncfg" "go.etcd.io/bbolt" ) +type Bolt struct { + DBTimeout time.Duration `long:"dbtimeout" description:"Specify the timeout value used when opening the database."` + DataDir string `long:"data-dir" description:"Lnd data dir where bolt dbs are located."` + TowerDir string `long:"tower-dir" description:"Lnd watchtower dir where bolt dbs for the watchtower server are located."` +} + +type Sqlite struct { + DataDir string `long:"data-dir" description:"Lnd data dir where sqlite dbs are located."` + TowerDir string `long:"tower-dir" description:"Lnd watchtower dir where sqlite dbs for the watchtower server are located."` + Config *sqlite.Config `group:"sqlite-config" namespace:"sqlite-config" description:"Sqlite config."` +} + +type DB struct { + Backend string `long:"backend" description:"The selected database backend."` + Etcd *etcd.Config `group:"etcd" namespace:"etcd" description:"Etcd settings."` + Bolt *Bolt `group:"bolt" namespace:"bolt" description:"Bolt settings."` + Postgres *postgres.Config `group:"postgres" namespace:"postgres" description:"Postgres settings."` + Sqlite *Sqlite `group:"sqlite" namespace:"sqlite" description:"Sqlite settings."` +} + const ( DefaultOpenTimeout = time.Second * 10 ) -func OpenDB(dbPath string, readonly bool) (*channeldb.DB, error) { - backend, err := openDB(dbPath, false, readonly, DefaultOpenTimeout) - if errors.Is(err, bbolt.ErrTimeout) { - return nil, fmt.Errorf("error opening %s: make sure lnd is "+ - "not running, database is locked by another process", - dbPath) +// Init should be called upon start to pre-initialize database for sql +// backends. If max connections are not set, the amount of connections will be +// unlimited however we only use one connection during the migration. +func (db DB) Init() error { + // Start embedded etcd server if requested. + switch { + case db.Backend == lncfg.PostgresBackend: + sqlbase.Init(db.Postgres.MaxConnections) + + case db.Backend == lncfg.SqliteBackend: + sqlbase.Init(db.Sqlite.Config.MaxConnections) + } + + return nil +} + +func openDB(cfg DB, prefix, network string) (kvdb.Backend, error) { + backend := cfg.Backend + + // Init the db connections for sql backends. + err := cfg.Init() + if err != nil { + return nil, err + } + + // Settings to open a particular db backend. + var args []interface{} + + switch backend { + case lncfg.BoltBackend: + // Directories where the db files are located. + graphDir := filepath.Join(cfg.Bolt.DataDir, "graph", network) + walletDir := filepath.Join( + cfg.Bolt.DataDir, "chain", "bitcoin", network, + ) + towerServerDir := filepath.Join( + cfg.Bolt.TowerDir, "bitcoin", network, + ) + + // Path to the db file. + var path string + switch prefix { + case lncfg.NSChannelDB: + path = filepath.Join(graphDir, lncfg.ChannelDBName) + + case lncfg.NSMacaroonDB: + path = filepath.Join(walletDir, lncfg.MacaroonDBName) + + case lncfg.NSDecayedLogDB: + path = filepath.Join(graphDir, lncfg.DecayedLogDbName) + + case lncfg.NSTowerClientDB: + path = filepath.Join(graphDir, lncfg.TowerClientDBName) + + case lncfg.NSTowerServerDB: + path = filepath.Join( + towerServerDir, lncfg.TowerServerDBName, + ) + + case lncfg.NSWalletDB: + path = filepath.Join(walletDir, lncfg.WalletDBName) + } + + const ( + noFreelistSync = true + timeout = time.Minute + ) + + args = []interface{}{ + path, noFreelistSync, timeout, + } + backend = kvdb.BoltBackendName + // log("Opening bbolt backend at %s for prefix '%s'", path, prefix) + + case kvdb.EtcdBackendName: + args = []interface{}{ + context.Background(), + cfg.Etcd.CloneWithSubNamespace(prefix), + } + + case kvdb.PostgresBackendName: + args = []interface{}{ + context.Background(), + &postgres.Config{ + Dsn: cfg.Postgres.Dsn, + Timeout: time.Minute, + MaxConnections: 10, + }, + prefix, + } + + case kvdb.SqliteBackendName: + // Directories where the db files are located. + graphDir := filepath.Join(cfg.Sqlite.DataDir, "graph", network) + walletDir := filepath.Join( + cfg.Sqlite.DataDir, "chain", "bitcoin", network, + ) + towerServerDir := filepath.Join( + cfg.Sqlite.TowerDir, "bitcoin", network, + ) + graphDir = cfg.Sqlite.DataDir + + var dbName string + var path string + switch prefix { + case lncfg.NSChannelDB: + path = graphDir + dbName = lncfg.SqliteChannelDBName + case lncfg.NSMacaroonDB: + path = walletDir + dbName = lncfg.SqliteChainDBName + + case lncfg.NSDecayedLogDB: + path = graphDir + dbName = lncfg.SqliteChannelDBName + + case lncfg.NSTowerClientDB: + path = graphDir + dbName = lncfg.SqliteChannelDBName + + case lncfg.NSTowerServerDB: + path = towerServerDir + dbName = lncfg.SqliteChannelDBName + + case lncfg.NSWalletDB: + path = walletDir + dbName = lncfg.SqliteChainDBName + + case lncfg.NSNeutrinoDB: + dbName = lncfg.SqliteNeutrinoDBName + } + + args = []interface{}{ + context.Background(), + &sqlite.Config{ + Timeout: time.Minute, + }, + path, + dbName, + prefix, + } + + default: + return nil, fmt.Errorf("unknown backend: %v", backend) } + + return kvdb.Open(backend, args...) +} + +func OpenChannelDB(cfg DB, network string) (*channeldb.DB, error) { + backend, err := openDB(cfg, lncfg.NSChannelDB, network) if err != nil { return nil, err } + // if errors.Is(err, bbolt.ErrTimeout) { + // return nil, fmt.Errorf("error opening %s: make sure lnd is "+ + // "not running, database is locked by another process", + // dbPath) + // } + // if err != nil { + // return nil, err + // } + return channeldb.CreateWithBackend( backend, channeldb.OptionSetUseGraphCache(false), - channeldb.OptionNoMigration(readonly), + channeldb.OptionNoMigration(true), ) } @@ -477,24 +657,24 @@ func fileExists(name string) bool { return true } -// openDB opens the database at the provided path. walletdb.ErrDbDoesNotExist -// is returned if the database doesn't exist and the create flag is not set. -func openDB(dbPath string, noFreelistSync bool, - readonly bool, timeout time.Duration) (kvdb.Backend, error) { +// // openDB opens the database at the provided path. walletdb.ErrDbDoesNotExist +// // is returned if the database doesn't exist and the create flag is not set. +// func openDB(dbPath string, noFreelistSync bool, +// readonly bool, timeout time.Duration) (kvdb.Backend, error) { - if !fileExists(dbPath) { - return nil, walletdb.ErrDbDoesNotExist - } +// if !fileExists(dbPath) { +// return nil, walletdb.ErrDbDoesNotExist +// } - // Specify bbolt freelist options to reduce heap pressure in case the - // freelist grows to be very large. - options := &bbolt.Options{ - NoFreelistSync: noFreelistSync, - FreelistType: bbolt.FreelistMapType, - Timeout: timeout, - ReadOnly: readonly, - } +// // Specify bbolt freelist options to reduce heap pressure in case the +// // freelist grows to be very large. +// options := &bbolt.Options{ +// NoFreelistSync: noFreelistSync, +// FreelistType: bbolt.FreelistMapType, +// Timeout: timeout, +// ReadOnly: readonly, +// } - boltDB, err := bbolt.Open(dbPath, 0600, options) - return &backend{db: boltDB}, convertErr(err) -} +// boltDB, err := bbolt.Open(dbPath, 0600, options) +// return &backend{db: boltDB}, convertErr(err) +// }