From 6c008ff8fb7c7b3f2142331c5392d86246c0ad1b Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Mon, 11 Nov 2024 16:18:02 +0200 Subject: [PATCH] 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. --- config.go | 2 ++ config_builder.go | 24 ++++++++++++++++++++++++ graph/sources/chan_graph.go | 21 +++++++++++++++++++++ graph/sources/interfaces.go | 6 ++++++ lnd.go | 7 ++++++- server.go | 8 +++++++- 6 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 graph/sources/chan_graph.go create mode 100644 graph/sources/interfaces.go diff --git a/config.go b/config.go index 04a491765..ef0a8fc1e 100644 --- a/config.go +++ b/config.go @@ -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, } } diff --git a/config_builder.go b/config_builder.go index 42650bb68..30173a6de 100644 --- a/config_builder.go +++ b/config_builder.go @@ -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 diff --git a/graph/sources/chan_graph.go b/graph/sources/chan_graph.go new file mode 100644 index 000000000..a2acfcf6d --- /dev/null +++ b/graph/sources/chan_graph.go @@ -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, + } +} diff --git a/graph/sources/interfaces.go b/graph/sources/interfaces.go new file mode 100644 index 000000000..99698d722 --- /dev/null +++ b/graph/sources/interfaces.go @@ -0,0 +1,6 @@ +package sources + +// GraphSource defines the read-only graph interface required by LND for graph +// related queries. +type GraphSource interface { +} diff --git a/lnd.go b/lnd.go index f51181195..07cf463e4 100644 --- a/lnd.go +++ b/lnd.go @@ -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) diff --git a/server.go b/server.go index df414583a..6f8c8c97a 100644 --- a/server.go +++ b/server.go @@ -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,