Skip to content

WIP: support native sql config #7918

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -1840,6 +1840,14 @@ func (c *Config) graphDatabaseDir() string {
func (c *Config) ImplementationConfig(
interceptor signal.Interceptor) *ImplementationCfg {

// Create a default database builder.
dbBuilder := NewDefaultDatabaseBuilder(c, ltndLog)

// Use native sql db builder if specified.
if c.DB.Backend == lncfg.NativeSQLBackend {
dbBuilder = NewDefaultDatabaseBuilder(c, ltndLog)
}

// If we're using a remote signer, we still need the base wallet as a
// watch-only source of chain and address data. But we don't need any
// private key material in that btcwallet base wallet.
Expand All @@ -1849,12 +1857,10 @@ func (c *Config) ImplementationConfig(
c.RemoteSigner.MigrateWatchOnly,
)
return &ImplementationCfg{
GrpcRegistrar: rpcImpl,
RestRegistrar: rpcImpl,
ExternalValidator: rpcImpl,
DatabaseBuilder: NewDefaultDatabaseBuilder(
c, ltndLog,
),
GrpcRegistrar: rpcImpl,
RestRegistrar: rpcImpl,
ExternalValidator: rpcImpl,
DatabaseBuilder: dbBuilder,
WalletConfigBuilder: rpcImpl,
ChainControlBuilder: rpcImpl,
}
Expand All @@ -1865,7 +1871,7 @@ func (c *Config) ImplementationConfig(
GrpcRegistrar: defaultImpl,
RestRegistrar: defaultImpl,
ExternalValidator: defaultImpl,
DatabaseBuilder: NewDefaultDatabaseBuilder(c, ltndLog),
DatabaseBuilder: dbBuilder,
WalletConfigBuilder: defaultImpl,
ChainControlBuilder: defaultImpl,
}
Expand Down
58 changes: 58 additions & 0 deletions config_builder_db.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package lnd

import (
"context"

"github.com/btcsuite/btclog"
)

// SQLDatabaseBuilder is a type that builds the SQL database backends for lnd,
type SQLDatabaseBuilder struct {
cfg *Config
logger btclog.Logger
}

// Compile time assertion that SQLDatabaseBuilder implements DatabaseBuilder.
var _ DatabaseBuilder = (*SQLDatabaseBuilder)(nil)

// NewSQLDatabaseBuilder returns a new instance of the SQL database builder.
func NewSQLDatabaseBuilder(cfg *Config,
logger btclog.Logger) *SQLDatabaseBuilder {

return &SQLDatabaseBuilder{
cfg: cfg,
logger: logger,
}
}

// BuildDatabase...
func (d *SQLDatabaseBuilder) BuildDatabase(
ctx context.Context) (*DatabaseInstances, func(), error) {

// TODO(yy): Fix the dup logs.
d.logger.Infof("Opening database, this might take a few minutes...")

// Get the default database builder.
//
// TODO(yy): remove it once we have migrated all kvdb to native sql.
defaultBuiler := NewDefaultDatabaseBuilder(d.cfg, d.logger)

// Build the default database instance. Though the database could be
// SQL, the actual data store still uses key-value format.
dbs, cleanUp, err := defaultBuiler.BuildDatabase(ctx)
if err != nil {
return nil, nil, err
}

// // Build the SQL database instance.
// sqlDB, err := NewSQLDB(d.cfg)

// // Map the database instances to the SQL database instances.
// dbs.InvoiceDB = sqlDB.NewInvoiceDB(d.cfg)
// dbs.PaymentDB = sqlDB.NewPaymentStore(d.cfg)

// TODO(yy): overwrite more sql tables here
// NOTE(yy): all the mappings should be removed eventually.

return dbs, cleanUp, nil
}
35 changes: 27 additions & 8 deletions lncfg/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/lightningnetwork/lnd/kvdb/sqlite"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lnwallet/btcwallet"
"github.com/lightningnetwork/lnd/sqldb"
)

const (
Expand All @@ -33,6 +34,7 @@ const (
EtcdBackend = "etcd"
PostgresBackend = "postgres"
SqliteBackend = "sqlite"
NativeSQLBackend = "sql"
DefaultBatchCommitInterval = 500 * time.Millisecond

defaultPostgresMaxConnections = 50
Expand Down Expand Up @@ -66,6 +68,17 @@ const (
NSNeutrinoDB = "neutrinodb"
)

// KVDB holds the config values for kvdb backend.
//
//nolint:lll
type KVDB struct {
Backend string `long:"backend" description:"The selected database backend." hidden:"true"`
Bolt *kvdb.BoltConfig `group:"kvdb.bolt" namespace:"bolt" description:"Bolt settings."`
Etcd *etcd.Config `group:"kvdb.etcd" namespace:"etcd" description:"Etcd settings."`
Postgres *postgres.Config `group:"kvdb.postgres" namespace:"postgres" description:"Postgres settings."`
Sqlite *sqlite.Config `group:"kvdb.sqlite" namespace:"sqlite" description:"Sqlite settings."`
}

// DB holds database configuration for LND.
//
//nolint:lll
Expand All @@ -74,19 +87,20 @@ type DB struct {

BatchCommitInterval time.Duration `long:"batch-commit-interval" description:"The maximum duration the channel graph batch schedulers will wait before attempting to commit a batch of pending updates. This can be tradeoff database contenion for commit latency."`

Etcd *etcd.Config `group:"etcd" namespace:"etcd" description:"Etcd settings."`

Bolt *kvdb.BoltConfig `group:"bolt" namespace:"bolt" description:"Bolt settings."`

Postgres *postgres.Config `group:"postgres" namespace:"postgres" description:"Postgres settings."`

Sqlite *sqlite.Config `group:"sqlite" namespace:"sqlite" description:"Sqlite settings."`

NoGraphCache bool `long:"no-graph-cache" description:"Don't use the in-memory graph cache for path finding. Much slower but uses less RAM. Can only be used with a bolt database backend."`

PruneRevocation bool `long:"prune-revocation" description:"Run the optional migration that prunes the revocation logs to save disk space."`

NoRevLogAmtData bool `long:"no-rev-log-amt-data" description:"If set, the to-local and to-remote output amounts of revoked commitment transactions will not be stored in the revocation log. Note that once this data is lost, a watchtower client will not be able to back up the revoked state."`

KVDB *KVDB `group:"kvdb" namespace:"kvdb" description:"key-value database settings."`
NativeSQL *sqldb.Config `group:"sql" namespace:"sql" description:"Native SQL settings."`

// Deprecated fields.
Etcd *etcd.Config `group:"etcd" namespace:"etcd" description:"Etcd settings." hidden:"true"`
Bolt *kvdb.BoltConfig `group:"bolt" namespace:"bolt" description:"Bolt settings." hidden:"true"`
Postgres *postgres.Config `group:"postgres" namespace:"postgres" description:"Postgres settings." hidden:"true"`
Sqlite *sqlite.Config `group:"sqlite" namespace:"sqlite" description:"Sqlite settings." hidden:"true"`
}

// DefaultDB creates and returns a new default DB config.
Expand Down Expand Up @@ -127,6 +141,11 @@ func (db *DB) Validate() error {
return fmt.Errorf("etcd host must be set")
}

case NativeSQLBackend:
if err := db.NativeSQL.Validate(); err != nil {
return fmt.Errorf("native sql: %w", err)
}

default:
return fmt.Errorf("unknown backend, must be either '%v', "+
"'%v', '%v' or '%v'", BoltBackend, EtcdBackend,
Expand Down
49 changes: 49 additions & 0 deletions sqldb/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package sqldb

import (
"errors"
"fmt"

"github.com/lightningnetwork/lnd/kvdb/postgres"
"github.com/lightningnetwork/lnd/kvdb/sqlite"
)

const (
PostgresBackend = "postgres"
SqliteBackend = "sqlite"
)

var (
ErrMissingConfig = errors.New("missing backend config")
ErrUnknownBackend = errors.New("unknown backend")
)

//nolint:lll
type Config struct {
Backend string `long:"backend" description:"The selected database backend." hidden:"true"`

Postgres *postgres.Config `group:"sql.postgres" namespace:"postgres" description:"Postgres settings."`

Sqlite *sqlite.Config `group:"sql.sqlite" namespace:"sqlite" description:"Sqlite settings."`
}

func (c *Config) Validate() error {
switch c.Backend {
case PostgresBackend:
if c.Postgres == nil {
return fmt.Errorf("%w for postgres", ErrMissingConfig)
}

return c.Postgres.Validate()

case SqliteBackend:
if c.Sqlite == nil {
return fmt.Errorf("%w for sqlite", ErrMissingConfig)
}

return c.Sqlite.Validate()

default:
return fmt.Errorf("%w: %v", ErrUnknownBackend, c.Backend)
}
}