From 9992e5c0b5523975f4a16893c8c1f56a1ddd9d89 Mon Sep 17 00:00:00 2001 From: Andras Banki-Horvath Date: Tue, 9 Feb 2021 17:44:43 +0100 Subject: [PATCH] etcd: decouple embedded etcd instance startup This refactor changes how we instantiate the etcd based Backend to allow separate initialization and startup for the embedded instance. --- channeldb/kvdb/backend.go | 10 +++++++++- channeldb/kvdb/kvdb_etcd.go | 29 +++-------------------------- channeldb/kvdb/kvdb_no_etcd.go | 15 +++------------ lncfg/db.go | 32 ++++++++++++++++++++++++-------- lnd.go | 7 +++++++ 5 files changed, 46 insertions(+), 47 deletions(-) diff --git a/channeldb/kvdb/backend.go b/channeldb/kvdb/backend.go index 309f7540..23dccddf 100644 --- a/channeldb/kvdb/backend.go +++ b/channeldb/kvdb/backend.go @@ -1,6 +1,7 @@ package kvdb import ( + "context" "encoding/binary" "fmt" "io/ioutil" @@ -253,7 +254,14 @@ func GetTestBackend(path, name string) (Backend, func(), error) { } return db, empty, nil } else if TestBackend == EtcdBackendName { - return GetEtcdTestBackend(path, 0, 0) + etcdConfig, cancel, err := StartEtcdTestBackend(path, 0, 0) + if err != nil { + return nil, empty, err + } + backend, err := Open( + EtcdBackendName, context.TODO(), etcdConfig, + ) + return backend, cancel, err } return nil, nil, fmt.Errorf("unknown backend") diff --git a/channeldb/kvdb/kvdb_etcd.go b/channeldb/kvdb/kvdb_etcd.go index 95dc22a8..81e2ee42 100644 --- a/channeldb/kvdb/kvdb_etcd.go +++ b/channeldb/kvdb/kvdb_etcd.go @@ -3,8 +3,6 @@ package kvdb import ( - "context" - "github.com/lightningnetwork/lnd/channeldb/kvdb/etcd" ) @@ -12,33 +10,12 @@ import ( // defined, allowing testing our database code with etcd backend. const TestBackend = EtcdBackendName -// GetEtcdBackend returns an etcd backend configured according to the -// passed etcdConfig. -func GetEtcdBackend(ctx context.Context, etcdConfig *etcd.Config) ( - Backend, error) { - - return Open(EtcdBackendName, etcdConfig) -} - // GetEtcdTestBackend creates an embedded etcd backend for testing // storig the database at the passed path. -func GetEtcdTestBackend(path string, clientPort, peerPort uint16) ( - Backend, func(), error) { +func StartEtcdTestBackend(path string, clientPort, peerPort uint16) ( + *etcd.Config, func(), error) { - empty := func() {} - - config, cleanup, err := etcd.NewEmbeddedEtcdInstance( + return etcd.NewEmbeddedEtcdInstance( path, clientPort, peerPort, ) - if err != nil { - return nil, empty, err - } - - backend, err := Open(EtcdBackendName, context.Background(), config) - if err != nil { - cleanup() - return nil, empty, err - } - - return backend, cleanup, nil } diff --git a/channeldb/kvdb/kvdb_no_etcd.go b/channeldb/kvdb/kvdb_no_etcd.go index 4b6f8477..5e103093 100644 --- a/channeldb/kvdb/kvdb_no_etcd.go +++ b/channeldb/kvdb/kvdb_no_etcd.go @@ -3,7 +3,6 @@ package kvdb import ( - "context" "fmt" "github.com/lightningnetwork/lnd/channeldb/kvdb/etcd" @@ -15,17 +14,9 @@ const TestBackend = BoltBackendName var errEtcdNotAvailable = fmt.Errorf("etcd backend not available") -// GetEtcdBackend is a stub returning nil and errEtcdNotAvailable error. -func GetEtcdBackend(ctx context.Context, etcdConfig *etcd.Config) ( - Backend, error) { - - return nil, errEtcdNotAvailable -} - -// GetTestEtcdBackend is a stub returning nil, an empty closure and an -// errEtcdNotAvailable error. -func GetEtcdTestBackend(path string, clientPort, peerPort uint16) ( - Backend, func(), error) { +// StartEtcdTestBackend is a stub returning nil, and errEtcdNotAvailable error. +func StartEtcdTestBackend(path string, clientPort, peerPort uint16) ( + *etcd.Config, func(), error) { return nil, func() {}, errEtcdNotAvailable } diff --git a/lncfg/db.go b/lncfg/db.go index 3cc59f79..e349400a 100644 --- a/lncfg/db.go +++ b/lncfg/db.go @@ -57,6 +57,27 @@ func (db *DB) Validate() error { return nil } +// Init should be called upon start to pre-initialize database access dependent +// on configuration. +func (db *DB) Init(ctx context.Context, dbPath string) error { + // Start embedded etcd server if requested. + if db.Backend == EtcdBackend && db.Etcd.Embedded { + cfg, _, err := kvdb.StartEtcdTestBackend( + dbPath, db.Etcd.EmbeddedClientPort, + db.Etcd.EmbeddedPeerPort, + ) + if err != nil { + return err + } + + // Override the original config with the config for + // the embedded instance. + db.Etcd = cfg + } + + return nil +} + // DatabaseBackends is a two-tuple that holds the set of active database // backends for the daemon. The two backends we expose are the local database // backend, and the remote backend. The LocalDB attribute will always be @@ -83,14 +104,9 @@ func (db *DB) GetBackends(ctx context.Context, dbPath string) ( ) if db.Backend == EtcdBackend { - if db.Etcd.Embedded { - remoteDB, _, err = kvdb.GetEtcdTestBackend( - dbPath, db.Etcd.EmbeddedClientPort, - db.Etcd.EmbeddedPeerPort, - ) - } else { - remoteDB, err = kvdb.GetEtcdBackend(ctx, db.Etcd) - } + remoteDB, err = kvdb.Open( + kvdb.EtcdBackendName, ctx, db.Etcd, + ) if err != nil { return nil, err } diff --git a/lnd.go b/lnd.go index bebc8e9a..a7703858 100644 --- a/lnd.go +++ b/lnd.go @@ -234,6 +234,13 @@ func Main(cfg *Config, lisCfg ListenerCfg, interceptor signal.Interceptor) error ctx, cancel := context.WithCancel(ctx) defer cancel() + // Run configuration dependent DB pre-initialization. Note that this + // needs to be done early and once during the startup process, before + // any DB access. + if err := cfg.DB.Init(ctx, cfg.localDatabaseDir()); err != nil { + return err + } + localChanDB, remoteChanDB, cleanUp, err := initializeDatabases(ctx, cfg) switch { case err == channeldb.ErrDryRunMigrationOK: