lncfg: add configuration for user specified db backend

This commit extends lncfg to support user specified database backend.
This supports configuration for both bolt and etcd (while only allowing
one or the other).
This commit is contained in:
Andras Banki-Horvath 2020-03-13 17:05:28 +01:00
parent 859a457e48
commit 9d57c1a6b4
3 changed files with 99 additions and 6 deletions

@ -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."` 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 // registeredChains keeps track of all chains that have been registered
// with the daemon. // with the daemon.
registeredChains *chainRegistry registeredChains *chainRegistry
@ -358,6 +360,7 @@ func DefaultConfig() Config {
}, },
MaxOutgoingCltvExpiry: htlcswitch.DefaultMaxOutgoingCltvExpiry, MaxOutgoingCltvExpiry: htlcswitch.DefaultMaxOutgoingCltvExpiry,
MaxChannelFeeAllocation: htlcswitch.DefaultMaxLinkFeeAllocation, MaxChannelFeeAllocation: htlcswitch.DefaultMaxLinkFeeAllocation,
DB: lncfg.DefaultDB(),
registeredChains: newChainRegistry(), registeredChains: newChainRegistry(),
} }
} }
@ -1073,6 +1076,7 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
cfg.Workers, cfg.Workers,
cfg.Caches, cfg.Caches,
cfg.WtClient, cfg.WtClient,
cfg.DB,
) )
if err != nil { if err != nil {
return nil, err return nil, err
@ -1090,6 +1094,14 @@ func ValidateConfig(cfg Config, usageMessage string) (*Config, error) {
return &cfg, err 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 // CleanAndExpandPath expands environment variables and leading ~ in the
// passed path, cleans the result, and returns it. // passed path, cleans the result, and returns it.
// This function is taken from https://github.com/btcsuite/btcd // This function is taken from https://github.com/btcsuite/btcd

85
lncfg/db.go Normal file

@ -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)

8
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. // 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 " + ltndLog.Infof("Opening the main database, this might take a few " +
"minutes...") "minutes...")
@ -258,7 +254,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
// network related metadata. // network related metadata.
startOpenTime := time.Now() startOpenTime := time.Now()
chanDB, err := channeldb.Open( chanDB, err := channeldb.Open(
graphDir, cfg.localDatabaseDir(),
channeldb.OptionSetRejectCacheSize(cfg.Caches.RejectCacheSize), channeldb.OptionSetRejectCacheSize(cfg.Caches.RejectCacheSize),
channeldb.OptionSetChannelCacheSize(cfg.Caches.ChannelCacheSize), channeldb.OptionSetChannelCacheSize(cfg.Caches.ChannelCacheSize),
channeldb.OptionSetSyncFreelist(cfg.SyncFreelist), channeldb.OptionSetSyncFreelist(cfg.SyncFreelist),
@ -493,7 +489,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, shutdownChan <-chan struct{}) error {
var towerClientDB *wtdb.ClientDB var towerClientDB *wtdb.ClientDB
if cfg.WtClient.Active { if cfg.WtClient.Active {
var err error var err error
towerClientDB, err = wtdb.OpenClientDB(graphDir) towerClientDB, err = wtdb.OpenClientDB(cfg.localDatabaseDir())
if err != nil { if err != nil {
err := fmt.Errorf("unable to open watchtower client "+ err := fmt.Errorf("unable to open watchtower client "+
"database: %v", err) "database: %v", err)