diff --git a/config.go b/config.go index 3fe0059f..840f2765 100644 --- a/config.go +++ b/config.go @@ -248,6 +248,8 @@ type Config struct { AllowCircularRoute bool `long:"allow-circular-route" description:"If true, our node will allow htlc forwards that arrive and depart on the same channel."` + DB *lncfg.DB `group:"db" namespace:"db"` + // registeredChains keeps track of all chains that have been registered // with the daemon. registeredChains *chainRegistry @@ -358,6 +360,7 @@ func DefaultConfig() Config { }, MaxOutgoingCltvExpiry: htlcswitch.DefaultMaxOutgoingCltvExpiry, MaxChannelFeeAllocation: htlcswitch.DefaultMaxLinkFeeAllocation, + DB: lncfg.DefaultDB(), registeredChains: newChainRegistry(), } } @@ -1073,6 +1076,7 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) { cfg.Workers, cfg.Caches, cfg.WtClient, + cfg.DB, ) if err != nil { return nil, err @@ -1090,6 +1094,14 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) { return &cfg, err } +// localDatabaseDir returns the default directory where the +// local bolt db files are stored. +func (c *config) localDatabaseDir() string { + return filepath.Join(cfg.DataDir, + defaultGraphSubDirname, + normalizeNetwork(activeNetParams.Name)) +} + // CleanAndExpandPath expands environment variables and leading ~ in the // passed path, cleans the result, and returns it. // This function is taken from https://github.com/btcsuite/btcd diff --git a/lncfg/db.go b/lncfg/db.go new file mode 100644 index 00000000..4b887aa1 --- /dev/null +++ b/lncfg/db.go @@ -0,0 +1,85 @@ +package lncfg + +import ( + "fmt" + + "github.com/lightningnetwork/lnd/channeldb/kvdb" + "github.com/lightningnetwork/lnd/channeldb/kvdb/etcd" +) + +const ( + dbName = "channel.db" + boltBackend = "bolt" + etcdBackend = "etcd" +) + +// BoltDB holds bolt configuration. +type BoltDB struct { + NoFreeListSync bool `long:"nofreelistsync" description:"If true, prevents the database from syncing its freelist to disk"` +} + +// EtcdDB hold etcd configuration. +type EtcdDB struct { + Host string `long:"host" description:"Etcd database host."` + + User string `long:"user" description:"Etcd database user."` + + Pass string `long:"pass" description:"Password for the database user."` + + CollectStats bool `long:"collect_stats" description:"Wheter to collect etcd commit stats."` +} + +// DB holds database configuration for LND. +type DB struct { + Backend string `long:"backend" description:"The selected database backend."` + + Etcd *EtcdDB `group:"etcd" namespace:"etcd" description:"Etcd settings."` + + Bolt *BoltDB `group:"bolt" namespace:"bolt" description:"Bolt settings."` +} + +// NewDB creates and returns a new default DB config. +func DefaultDB() *DB { + return &DB{ + Backend: boltBackend, + Bolt: &BoltDB{ + NoFreeListSync: true, + }, + } +} + +// Validate validates the DB config. +func (db *DB) Validate() error { + switch db.Backend { + case boltBackend: + + case etcdBackend: + if db.Etcd.Host == "" { + return fmt.Errorf("etcd host must be set") + } + + default: + return fmt.Errorf("unknown backend, must be either \"%v\" or \"%v\"", + boltBackend, etcdBackend) + } + + return nil +} + +// GetBackend returns a kvdb.Backend as set in the DB config. +func (db *DB) GetBackend(path string) (kvdb.Backend, error) { + if db.Backend == etcdBackend { + backendConfig := etcd.BackendConfig{ + Host: db.Etcd.Host, + User: db.Etcd.User, + Pass: db.Etcd.Pass, + CollectCommitStats: db.Etcd.CollectStats, + } + return kvdb.Open(kvdb.EtcdBackendName, backendConfig) + } + + return kvdb.GetBoltBackend(path, dbName, db.Bolt.NoFreeListSync) +} + +// Compile-time constraint to ensure Workers implements the Validator interface. +var _ Validator = (*DB)(nil) diff --git a/lnd.go b/lnd.go index 578f6845..125990a2 100644 --- a/lnd.go +++ b/lnd.go @@ -247,10 +247,6 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error { } // Create the network-segmented directory for the channel database. - graphDir := filepath.Join(cfg.DataDir, - defaultGraphSubDirname, - normalizeNetwork(activeNetParams.Name)) - ltndLog.Infof("Opening the main database, this might take a few " + "minutes...") @@ -258,7 +254,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error { // network related metadata. startOpenTime := time.Now() chanDB, err := channeldb.Open( - graphDir, + cfg.localDatabaseDir(), channeldb.OptionSetRejectCacheSize(cfg.Caches.RejectCacheSize), channeldb.OptionSetChannelCacheSize(cfg.Caches.ChannelCacheSize), channeldb.OptionSetSyncFreelist(cfg.SyncFreelist), @@ -493,7 +489,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error { var towerClientDB *wtdb.ClientDB if cfg.WtClient.Active { var err error - towerClientDB, err = wtdb.OpenClientDB(graphDir) + towerClientDB, err = wtdb.OpenClientDB(cfg.localDatabaseDir()) if err != nil { err := fmt.Errorf("unable to open watchtower client "+ "database: %v", err)