mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-11-18 01:56:55 +01:00
165 lines
5.0 KiB
Go
165 lines
5.0 KiB
Go
package sources
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/btcsuite/btcd/wire"
|
|
graphdb "github.com/lightningnetwork/lnd/graph/db"
|
|
"github.com/lightningnetwork/lnd/graph/db/models"
|
|
"github.com/lightningnetwork/lnd/graph/session"
|
|
"github.com/lightningnetwork/lnd/kvdb"
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
"github.com/lightningnetwork/lnd/routing/route"
|
|
)
|
|
|
|
// 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,
|
|
}
|
|
}
|
|
|
|
// NewPathFindTx returns a new read transaction that can be used for a single
|
|
// path finding session. Will return nil if the graph cache is enabled for the
|
|
// underlying graphdb.ChannelGraph.
|
|
//
|
|
// NOTE: this is part of the session.ReadOnlyGraph interface.
|
|
func (s *DBSource) NewPathFindTx(_ context.Context) (session.RTx, error) {
|
|
tx, err := s.db.NewPathFindTx()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return newKVDBRTx(tx), nil
|
|
}
|
|
|
|
// ForEachNodeDirectedChannel iterates through all channels of a given node,
|
|
// executing the passed callback on the directed edge representing the channel
|
|
// and its incoming policy. If the callback returns an error, then the
|
|
// iteration is halted with the error propagated back up to the caller. An
|
|
// optional read transaction may be provided. If it is, then it will be cast
|
|
// into a kvdb.RTx and passed into the callback.
|
|
//
|
|
// Unknown policies are passed into the callback as nil values.
|
|
//
|
|
// NOTE: this is part of the session.ReadOnlyGraph interface.
|
|
func (s *DBSource) ForEachNodeDirectedChannel(_ context.Context, tx session.RTx,
|
|
node route.Vertex,
|
|
cb func(channel *graphdb.DirectedChannel) error) error {
|
|
|
|
kvdbTx, err := extractKVDBRTx(tx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return s.db.ForEachNodeDirectedChannel(kvdbTx, node, cb)
|
|
}
|
|
|
|
// FetchNodeFeatures returns the features of a given node. If no features are
|
|
// known for the node, an empty feature vector is returned. An optional read
|
|
// transaction may be provided. If it is, then it will be cast into a kvdb.RTx
|
|
// and passed into the callback.
|
|
//
|
|
// NOTE: this is part of the graphsession.ReadOnlyGraph interface.
|
|
func (s *DBSource) FetchNodeFeatures(_ context.Context, tx session.RTx,
|
|
node route.Vertex) (*lnwire.FeatureVector, error) {
|
|
|
|
kvdbTx, err := extractKVDBRTx(tx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return s.db.FetchNodeFeatures(kvdbTx, node)
|
|
}
|
|
|
|
// FetchChannelEdgesByID attempts to look up the two directed edges for the
|
|
// channel identified by the channel ID. If the channel can't be found, then
|
|
// graphdb.ErrEdgeNotFound is returned.
|
|
//
|
|
// NOTE: this is part of the invoicesrpc.GraphSource interface.
|
|
func (s *DBSource) FetchChannelEdgesByID(_ context.Context,
|
|
chanID uint64) (*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
|
*models.ChannelEdgePolicy, error) {
|
|
|
|
return s.db.FetchChannelEdgesByID(chanID)
|
|
}
|
|
|
|
// IsPublicNode determines whether the node with the given public key is seen as
|
|
// a public node in the graph from the graph's source node's point of view.
|
|
//
|
|
// NOTE: this is part of the invoicesrpc.GraphSource interface.
|
|
func (s *DBSource) IsPublicNode(_ context.Context,
|
|
pubKey [33]byte) (bool, error) {
|
|
|
|
return s.db.IsPublicNode(pubKey)
|
|
}
|
|
|
|
// FetchChannelEdgesByOutpoint returns the channel edge info and most recent
|
|
// channel edge policies for a given outpoint.
|
|
//
|
|
// NOTE: this is part of the netann.ChannelGraph interface.
|
|
func (s *DBSource) FetchChannelEdgesByOutpoint(_ context.Context,
|
|
point *wire.OutPoint) (*models.ChannelEdgeInfo,
|
|
*models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) {
|
|
|
|
return s.db.FetchChannelEdgesByOutpoint(point)
|
|
}
|
|
|
|
// kvdbRTx is an implementation of graphdb.RTx backed by a KVDB database read
|
|
// transaction.
|
|
type kvdbRTx struct {
|
|
kvdb.RTx
|
|
}
|
|
|
|
// newKVDBRTx constructs a kvdbRTx instance backed by the given kvdb.RTx.
|
|
func newKVDBRTx(tx kvdb.RTx) *kvdbRTx {
|
|
return &kvdbRTx{tx}
|
|
}
|
|
|
|
// Close closes the underlying transaction.
|
|
//
|
|
// NOTE: this is part of the graphdb.RTx interface.
|
|
func (t *kvdbRTx) Close() error {
|
|
if t.RTx == nil {
|
|
return nil
|
|
}
|
|
|
|
return t.RTx.Rollback()
|
|
}
|
|
|
|
// MustImplementRTx is a helper method that ensures that the kvdbRTx type
|
|
// implements the RTx interface.
|
|
//
|
|
// NOTE: this is part of the graphdb.RTx interface.
|
|
func (t *kvdbRTx) MustImplementRTx() {}
|
|
|
|
// A compile-time assertion to ensure that kvdbRTx implements the RTx interface.
|
|
var _ session.RTx = (*kvdbRTx)(nil)
|
|
|
|
// extractKVDBRTx is a helper function that casts an RTx into a kvdbRTx and
|
|
// errors if the cast fails.
|
|
func extractKVDBRTx(tx session.RTx) (kvdb.RTx, error) {
|
|
if tx == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
kvdbTx, ok := tx.(*kvdbRTx)
|
|
if !ok {
|
|
return nil, fmt.Errorf("expected a graphdb.kvdbRTx, got %T", tx)
|
|
}
|
|
|
|
return kvdbTx, nil
|
|
}
|