multi: use single read transaction for path finding

This commit partially reverts bf27d05a.
To avoid creating multiple database transactions during a single path
finding operation, we create an explicit transaction when the cached
graph is instantiated.
We cache the source node to avoid needing to look that up for every path
finding session.
The database transaction will be nil in case of the in-memory graph.
This commit is contained in:
Oliver Gugger
2021-10-21 13:55:22 +02:00
parent 1fef2970cf
commit 0a2ccfc52b
9 changed files with 105 additions and 33 deletions

View File

@ -2,6 +2,7 @@ package routing
import (
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/routing/route"
)
@ -25,6 +26,7 @@ type routingGraph interface {
// database.
type CachedGraph struct {
graph *channeldb.ChannelGraph
tx kvdb.RTx
source route.Vertex
}
@ -32,27 +34,40 @@ type CachedGraph struct {
// interface.
var _ routingGraph = (*CachedGraph)(nil)
// NewCachedGraph instantiates a new db-connected routing graph. It implictly
// NewCachedGraph instantiates a new db-connected routing graph. It implicitly
// instantiates a new read transaction.
func NewCachedGraph(graph *channeldb.ChannelGraph) (*CachedGraph, error) {
sourceNode, err := graph.SourceNode()
func NewCachedGraph(sourceNode *channeldb.LightningNode,
graph *channeldb.ChannelGraph) (*CachedGraph, error) {
tx, err := graph.NewPathFindTx()
if err != nil {
return nil, err
}
return &CachedGraph{
graph: graph,
tx: tx,
source: sourceNode.PubKeyBytes,
}, nil
}
// close attempts to close the underlying db transaction. This is a no-op in
// case the underlying graph uses an in-memory cache.
func (g *CachedGraph) close() error {
if g.tx == nil {
return nil
}
return g.tx.Rollback()
}
// forEachNodeChannel calls the callback for every channel of the given node.
//
// NOTE: Part of the routingGraph interface.
func (g *CachedGraph) forEachNodeChannel(nodePub route.Vertex,
cb func(channel *channeldb.DirectedChannel) error) error {
return g.graph.ForEachNodeChannel(nodePub, cb)
return g.graph.ForEachNodeChannel(g.tx, nodePub, cb)
}
// sourceNode returns the source node of the graph.