lnd+graph: add GraphSource interface and implementation

This commit adds a new GraphSources interface that LND requires for
graph related read-only queries. As of this commit, the interface is
empty but it will be populated over the next couple of commits. We add
an implementation of this interface backed by a pointer to a
graphdb.ChannelGraph.

The infrustructure is put into place so that the GraphSoure provided to
LND can be overridden by a caller of the lnd.Main function. By default,
LND will satisfy the interface itself via the new `graphsource.DBSource`
struct.
This commit is contained in:
Elle Mouton
2024-11-11 16:18:02 +02:00
parent 755065b6ab
commit 6c008ff8fb
6 changed files with 66 additions and 2 deletions

View File

@@ -1802,6 +1802,7 @@ func (c *Config) ImplementationConfig(
),
WalletConfigBuilder: rpcImpl,
ChainControlBuilder: rpcImpl,
GraphProvider: rpcImpl,
}
}
@@ -1813,6 +1814,7 @@ func (c *Config) ImplementationConfig(
DatabaseBuilder: NewDefaultDatabaseBuilder(c, ltndLog),
WalletConfigBuilder: defaultImpl,
ChainControlBuilder: defaultImpl,
GraphProvider: defaultImpl,
}
}

View File

@@ -36,6 +36,7 @@ import (
"github.com/lightningnetwork/lnd/fn"
"github.com/lightningnetwork/lnd/funding"
graphdb "github.com/lightningnetwork/lnd/graph/db"
"github.com/lightningnetwork/lnd/graph/sources"
"github.com/lightningnetwork/lnd/invoices"
"github.com/lightningnetwork/lnd/keychain"
"github.com/lightningnetwork/lnd/kvdb"
@@ -125,6 +126,14 @@ type ChainControlBuilder interface {
*btcwallet.Config) (*chainreg.ChainControl, func(), error)
}
// GraphProvider is an interface that must be satisfied by any external system
// that wants to provide LND with graph information.
type GraphProvider interface {
// Graph returns the GraphSource that LND will use for read-only graph
// related queries.
Graph(context.Context, *DatabaseInstances) (sources.GraphSource, error)
}
// ImplementationCfg is a struct that holds all configuration items for
// components that can be implemented outside lnd itself.
type ImplementationCfg struct {
@@ -155,6 +164,10 @@ type ImplementationCfg struct {
// AuxComponents is a set of auxiliary components that can be used by
// lnd for certain custom channel types.
AuxComponents
// GraphProvider is a type that can provide a custom GraphSource for LND
// to use for read-only graph calls.
GraphProvider
}
// AuxComponents is a set of auxiliary components that can be used by lnd for
@@ -249,6 +262,17 @@ func (d *DefaultWalletImpl) RegisterGrpcSubserver(s *grpc.Server) error {
return nil
}
// Graph returns the GraphSource that LND will use for read-only graph related
// queries. By default, the GraphSource implementation is this LND node's
// backing graphdb.ChannelGraph.
//
// NOTE: this is part of the GraphProvider interface.
func (d *DefaultWalletImpl) Graph(_ context.Context,
dbs *DatabaseInstances) (sources.GraphSource, error) {
return sources.NewDBGSource(dbs.GraphDB), nil
}
// ValidateMacaroon extracts the macaroon from the context's gRPC metadata,
// checks its signature, makes sure all specified permissions for the called
// method are contained within and finally ensures all caveat conditions are

View File

@@ -0,0 +1,21 @@
package sources
import graphdb "github.com/lightningnetwork/lnd/graph/db"
// DBSource is an implementation of the GraphSource interface backed by a local
// persistence layer holding graph related data.
type DBSource struct {
db *graphdb.ChannelGraph
}
// A compile-time check to ensure that sources.DBSource implements the
// GraphSource interface.
var _ GraphSource = (*DBSource)(nil)
// NewDBGSource returns a new instance of the DBSource backed by a
// graphdb.ChannelGraph instance.
func NewDBGSource(db *graphdb.ChannelGraph) *DBSource {
return &DBSource{
db: db,
}
}

View File

@@ -0,0 +1,6 @@
package sources
// GraphSource defines the read-only graph interface required by LND for graph
// related queries.
type GraphSource interface {
}

7
lnd.go
View File

@@ -485,6 +485,11 @@ func Main(cfg *Config, lisCfg ListenerCfg, implCfg *ImplementationCfg,
return mkErr("error deriving node key: %v", err)
}
graphSource, err := implCfg.Graph(ctx, dbs)
if err != nil {
return mkErr("error obtaining graph source: %v", err)
}
if cfg.Tor.StreamIsolation && cfg.Tor.SkipProxyForClearNetTargets {
return errStreamIsolationWithProxySkip
}
@@ -601,7 +606,7 @@ func Main(cfg *Config, lisCfg ListenerCfg, implCfg *ImplementationCfg,
cfg, cfg.Listeners, dbs, activeChainControl, &idKeyDesc,
activeChainControl.Cfg.WalletUnlockParams.ChansToRestore,
multiAcceptor, torController, tlsManager, leaderElector,
implCfg,
graphSource, implCfg,
)
if err != nil {
return mkErr("unable to create server: %v", err)

View File

@@ -45,6 +45,7 @@ import (
graphdb "github.com/lightningnetwork/lnd/graph/db"
"github.com/lightningnetwork/lnd/graph/db/models"
graphsession "github.com/lightningnetwork/lnd/graph/session"
"github.com/lightningnetwork/lnd/graph/sources"
"github.com/lightningnetwork/lnd/healthcheck"
"github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/htlcswitch/hop"
@@ -261,6 +262,10 @@ type server struct {
graphDB *graphdb.ChannelGraph
// graphSource can be used for any read only graph queries. This may be
// implemented by this LND node or some other external source.
graphSource sources.GraphSource
chanStateDB *channeldb.ChannelStateDB
addrSource channeldb.AddrSource
@@ -507,7 +512,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
chansToRestore walletunlocker.ChannelsToRecover,
chanPredicate chanacceptor.ChannelAcceptor,
torController *tor.Controller, tlsManager *TLSManager,
leaderElector cluster.LeaderElector,
leaderElector cluster.LeaderElector, graphSource sources.GraphSource,
implCfg *ImplementationCfg) (*server, error) {
var (
@@ -613,6 +618,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
cfg: cfg,
implCfg: implCfg,
graphDB: dbs.GraphDB,
graphSource: graphSource,
chanStateDB: dbs.ChanStateDB.ChannelStateDB(),
addrSource: addrSource,
miscDB: dbs.ChanStateDB,