Merge pull request #10068 from ellemouton/graphResetForCallbacks
multi: let all V1Store `ForEach*` methods take a `reset` call-back
This commit is contained in:
31 files changed
+330
-168
No files matched your search
@@ -640,6 +640,9 @@ func (a *Agent) openChans(ctx context.Context, availableFunds btcutil.Amount,
|
|||||||
|
|
||||||
nodes[nID] = struct{}{}
|
nodes[nID] = struct{}{}
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
nodes = nil
|
||||||
|
addresses = nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("unable to get graph nodes: %w", err)
|
return fmt.Errorf("unable to get graph nodes: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -121,7 +121,7 @@ func (d *dbNode) ForEachChannel(ctx context.Context,
|
|||||||
//
|
//
|
||||||
// NOTE: Part of the autopilot.ChannelGraph interface.
|
// NOTE: Part of the autopilot.ChannelGraph interface.
|
||||||
func (d *databaseChannelGraph) ForEachNode(ctx context.Context,
|
func (d *databaseChannelGraph) ForEachNode(ctx context.Context,
|
||||||
cb func(context.Context, Node) error) error {
|
cb func(context.Context, Node) error, reset func()) error {
|
||||||
|
|
||||||
return d.db.ForEachNode(ctx, func(nodeTx graphdb.NodeRTx) error {
|
return d.db.ForEachNode(ctx, func(nodeTx graphdb.NodeRTx) error {
|
||||||
// We'll skip over any node that doesn't have any advertised
|
// We'll skip over any node that doesn't have any advertised
|
||||||
@@ -136,7 +136,7 @@ func (d *databaseChannelGraph) ForEachNode(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return cb(ctx, node)
|
return cb(ctx, node)
|
||||||
})
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// databaseChannelGraphCached wraps a channeldb.ChannelGraph instance with the
|
// databaseChannelGraphCached wraps a channeldb.ChannelGraph instance with the
|
||||||
@@ -217,7 +217,7 @@ func (nc dbNodeCached) ForEachChannel(ctx context.Context,
|
|||||||
//
|
//
|
||||||
// NOTE: Part of the autopilot.ChannelGraph interface.
|
// NOTE: Part of the autopilot.ChannelGraph interface.
|
||||||
func (dc *databaseChannelGraphCached) ForEachNode(ctx context.Context,
|
func (dc *databaseChannelGraphCached) ForEachNode(ctx context.Context,
|
||||||
cb func(context.Context, Node) error) error {
|
cb func(context.Context, Node) error, reset func()) error {
|
||||||
|
|
||||||
return dc.db.ForEachNodeCached(ctx, func(n route.Vertex,
|
return dc.db.ForEachNodeCached(ctx, func(n route.Vertex,
|
||||||
channels map[uint64]*graphdb.DirectedChannel) error {
|
channels map[uint64]*graphdb.DirectedChannel) error {
|
||||||
@@ -231,7 +231,7 @@ func (dc *databaseChannelGraphCached) ForEachNode(ctx context.Context,
|
|||||||
return cb(ctx, node)
|
return cb(ctx, node)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// memNode is a purely in-memory implementation of the autopilot.Node
|
// memNode is a purely in-memory implementation of the autopilot.Node
|
||||||
|
|||||||
@@ -85,7 +85,8 @@ type ChannelGraph interface {
|
|||||||
// ForEachNode is a higher-order function that should be called once
|
// ForEachNode is a higher-order function that should be called once
|
||||||
// for each connected node within the channel graph. If the passed
|
// for each connected node within the channel graph. If the passed
|
||||||
// callback returns an error, then execution should be terminated.
|
// callback returns an error, then execution should be terminated.
|
||||||
ForEachNode(context.Context, func(context.Context, Node) error) error
|
ForEachNode(context.Context, func(context.Context, Node) error,
|
||||||
|
func()) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeScore is a tuple mapping a NodeID to a score indicating the preference
|
// NodeScore is a tuple mapping a NodeID to a score indicating the preference
|
||||||
@@ -228,12 +229,13 @@ type GraphSource interface {
|
|||||||
// the callback returns an error, then the transaction is aborted and
|
// the callback returns an error, then the transaction is aborted and
|
||||||
// the iteration stops early. Any operations performed on the NodeTx
|
// the iteration stops early. Any operations performed on the NodeTx
|
||||||
// passed to the call-back are executed under the same read transaction.
|
// passed to the call-back are executed under the same read transaction.
|
||||||
ForEachNode(context.Context, func(graphdb.NodeRTx) error) error
|
ForEachNode(context.Context, func(graphdb.NodeRTx) error, func()) error
|
||||||
|
|
||||||
// ForEachNodeCached is similar to ForEachNode, but it utilizes the
|
// ForEachNodeCached is similar to ForEachNode, but it utilizes the
|
||||||
// channel graph cache if one is available. It is less consistent than
|
// channel graph cache if one is available. It is less consistent than
|
||||||
// ForEachNode since any further calls are made across multiple
|
// ForEachNode since any further calls are made across multiple
|
||||||
// transactions.
|
// transactions.
|
||||||
ForEachNodeCached(ctx context.Context, cb func(node route.Vertex,
|
ForEachNodeCached(ctx context.Context, cb func(node route.Vertex,
|
||||||
chans map[uint64]*graphdb.DirectedChannel) error) error
|
chans map[uint64]*graphdb.DirectedChannel) error,
|
||||||
|
reset func()) error
|
||||||
}
|
}
|
||||||
@@ -105,6 +105,9 @@ func (p *PrefAttachment) NodeScores(ctx context.Context, g ChannelGraph,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
allChans = nil
|
||||||
|
clear(seenChans)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -162,6 +165,9 @@ func (p *PrefAttachment) NodeScores(ctx context.Context, g ChannelGraph,
|
|||||||
log.Tracef("Counted %v channels for node %x", nodeChans, nID[:])
|
log.Tracef("Counted %v channels for node %x", nodeChans, nID[:])
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
maxChans = 0
|
||||||
|
clear(nodeChanNum)
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,10 +147,13 @@ func TestPrefAttachmentSelectTwoVertexes(t *testing.T) {
|
|||||||
// Get the score for all nodes found in the graph at
|
// Get the score for all nodes found in the graph at
|
||||||
// this point.
|
// this point.
|
||||||
nodes := make(map[NodeID]struct{})
|
nodes := make(map[NodeID]struct{})
|
||||||
err = graph.ForEachNode(ctx,
|
err = graph.ForEachNode(
|
||||||
|
ctx,
|
||||||
func(_ context.Context, n Node) error {
|
func(_ context.Context, n Node) error {
|
||||||
nodes[n.PubKey()] = struct{}{}
|
nodes[n.PubKey()] = struct{}{}
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
clear(nodes)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
require.NoError(t1, err)
|
require.NoError(t1, err)
|
||||||
@@ -257,7 +260,12 @@ func TestPrefAttachmentSelectGreedyAllocation(t *testing.T) {
|
|||||||
twoChans = twoChans || (numChans == 2)
|
twoChans = twoChans || (numChans == 2)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {
|
||||||
|
numNodes = 0
|
||||||
|
twoChans = false
|
||||||
|
clear(nodes)
|
||||||
|
},
|
||||||
|
)
|
||||||
require.NoError(t1, err)
|
require.NoError(t1, err)
|
||||||
|
|
||||||
require.EqualValues(t1, 3, numNodes)
|
require.EqualValues(t1, 3, numNodes)
|
||||||
@@ -338,7 +346,7 @@ func TestPrefAttachmentSelectSkipNodes(t *testing.T) {
|
|||||||
nodes[n.PubKey()] = struct{}{}
|
nodes[n.PubKey()] = struct{}{}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
}, func() {},
|
||||||
)
|
)
|
||||||
require.NoError(t1, err)
|
require.NoError(t1, err)
|
||||||
|
|
||||||
@@ -593,7 +601,7 @@ func newMemChannelGraph() *memChannelGraph {
|
|||||||
//
|
//
|
||||||
// NOTE: Part of the autopilot.ChannelGraph interface.
|
// NOTE: Part of the autopilot.ChannelGraph interface.
|
||||||
func (m *memChannelGraph) ForEachNode(ctx context.Context,
|
func (m *memChannelGraph) ForEachNode(ctx context.Context,
|
||||||
cb func(context.Context, Node) error) error {
|
cb func(context.Context, Node) error, _ func()) error {
|
||||||
|
|
||||||
for _, node := range m.graph {
|
for _, node := range m.graph {
|
||||||
if err := cb(ctx, node); err != nil {
|
if err := cb(ctx, node); err != nil {
|
||||||
@@ -736,7 +744,8 @@ func (t *testNodeTx) ForEachChannel(f func(*models.ChannelEdgeInfo,
|
|||||||
policy2 *models.ChannelEdgePolicy) error {
|
policy2 *models.ChannelEdgePolicy) error {
|
||||||
|
|
||||||
return f(edge, policy1, policy2)
|
return f(edge, policy1, policy2)
|
||||||
})
|
}, func() {},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testNodeTx) FetchNode(pub route.Vertex) (graphdb.NodeRTx, error) {
|
func (t *testNodeTx) FetchNode(pub route.Vertex) (graphdb.NodeRTx, error) {
|
||||||
|
|||||||
@@ -60,6 +60,10 @@ func NewSimpleGraph(ctx context.Context, g ChannelGraph) (*SimpleGraph, error) {
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
}, func() {
|
||||||
|
clear(adj)
|
||||||
|
clear(nodes)
|
||||||
|
nextIndex = 0
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -247,9 +247,9 @@ func (c *ChannelGraphBootstrapper) SampleNodeAddrs(_ context.Context,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
c.tried[nID] = struct{}{}
|
|
||||||
|
|
||||||
return errFound
|
return errFound
|
||||||
|
}, func() {
|
||||||
|
a = nil
|
||||||
})
|
})
|
||||||
if err != nil && !errors.Is(err, errFound) {
|
if err != nil && !errors.Is(err, errFound) {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -282,6 +282,14 @@ func (c *ChannelGraphBootstrapper) SampleNodeAddrs(_ context.Context,
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, addr := range sampleAddrs {
|
||||||
|
nID := autopilot.NodeID(
|
||||||
|
addr.IdentityKey.SerializeCompressed(),
|
||||||
|
)
|
||||||
|
|
||||||
|
c.tried[nID] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
addrs = append(addrs, sampleAddrs...)
|
addrs = append(addrs, sampleAddrs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1758,6 +1758,9 @@ func (d *AuthenticatedGossiper) retransmitStaleAnns(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
havePublicChannels = false
|
||||||
|
edgesToUpdate = nil
|
||||||
})
|
})
|
||||||
if err != nil && !errors.Is(err, graphdb.ErrGraphNoEdgesFound) {
|
if err != nil && !errors.Is(err, graphdb.ErrGraphNoEdgesFound) {
|
||||||
return fmt.Errorf("unable to retrieve outgoing channels: %w",
|
return fmt.Errorf("unable to retrieve outgoing channels: %w",
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ func (r *mockGraphSource) ForEachNode(
|
|||||||
|
|
||||||
func (r *mockGraphSource) ForAllOutgoingChannels(_ context.Context,
|
func (r *mockGraphSource) ForAllOutgoingChannels(_ context.Context,
|
||||||
cb func(i *models.ChannelEdgeInfo,
|
cb func(i *models.ChannelEdgeInfo,
|
||||||
c *models.ChannelEdgePolicy) error) error {
|
c *models.ChannelEdgePolicy) error, _ func()) error {
|
||||||
|
|
||||||
r.mu.Lock()
|
r.mu.Lock()
|
||||||
defer r.mu.Unlock()
|
defer r.mu.Unlock()
|
||||||
@@ -3728,10 +3728,8 @@ out:
|
|||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {})
|
||||||
if err != nil {
|
require.NoError(t, err)
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ctx.gossiper.PropagateChanPolicyUpdate(edgesToUpdate)
|
err = ctx.gossiper.PropagateChanPolicyUpdate(edgesToUpdate)
|
||||||
require.NoError(t, err, "unable to chan policies")
|
require.NoError(t, err, "unable to chan policies")
|
||||||
|
|||||||
+5
-4
@@ -1276,10 +1276,11 @@ func (b *Builder) FetchLightningNode(ctx context.Context,
|
|||||||
//
|
//
|
||||||
// NOTE: This method is part of the ChannelGraphSource interface.
|
// NOTE: This method is part of the ChannelGraphSource interface.
|
||||||
func (b *Builder) ForAllOutgoingChannels(ctx context.Context,
|
func (b *Builder) ForAllOutgoingChannels(ctx context.Context,
|
||||||
cb func(*models.ChannelEdgeInfo,
|
cb func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy) error,
|
||||||
*models.ChannelEdgePolicy) error) error {
|
reset func()) error {
|
||||||
|
|
||||||
return b.cfg.Graph.ForEachNodeChannel(ctx, b.cfg.SelfNode,
|
return b.cfg.Graph.ForEachNodeChannel(
|
||||||
|
ctx, b.cfg.SelfNode,
|
||||||
func(c *models.ChannelEdgeInfo, e *models.ChannelEdgePolicy,
|
func(c *models.ChannelEdgeInfo, e *models.ChannelEdgePolicy,
|
||||||
_ *models.ChannelEdgePolicy) error {
|
_ *models.ChannelEdgePolicy) error {
|
||||||
|
|
||||||
@@ -1289,7 +1290,7 @@ func (b *Builder) ForAllOutgoingChannels(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return cb(c, e)
|
return cb(c, e)
|
||||||
},
|
}, reset,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-9
@@ -170,7 +170,7 @@ func (c *ChannelGraph) populateCache(ctx context.Context) error {
|
|||||||
c.graphCache.AddNodeFeatures(node, features)
|
c.graphCache.AddNodeFeatures(node, features)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,8 @@ func (c *ChannelGraph) populateCache(ctx context.Context) error {
|
|||||||
c.graphCache.AddChannel(info, policy1, policy2)
|
c.graphCache.AddChannel(info, policy1, policy2)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {},
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -204,13 +205,13 @@ func (c *ChannelGraph) populateCache(ctx context.Context) error {
|
|||||||
//
|
//
|
||||||
// NOTE: this is part of the graphdb.NodeTraverser interface.
|
// NOTE: this is part of the graphdb.NodeTraverser interface.
|
||||||
func (c *ChannelGraph) ForEachNodeDirectedChannel(node route.Vertex,
|
func (c *ChannelGraph) ForEachNodeDirectedChannel(node route.Vertex,
|
||||||
cb func(channel *DirectedChannel) error) error {
|
cb func(channel *DirectedChannel) error, reset func()) error {
|
||||||
|
|
||||||
if c.graphCache != nil {
|
if c.graphCache != nil {
|
||||||
return c.graphCache.ForEachChannel(node, cb)
|
return c.graphCache.ForEachChannel(node, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.V1Store.ForEachNodeDirectedChannel(node, cb)
|
return c.V1Store.ForEachNodeDirectedChannel(node, cb, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchNodeFeatures returns the features of the given node. If no features are
|
// FetchNodeFeatures returns the features of the given node. If no features are
|
||||||
@@ -233,12 +234,14 @@ func (c *ChannelGraph) FetchNodeFeatures(node route.Vertex) (
|
|||||||
// instance which can be used to perform queries against the channel graph. If
|
// instance which can be used to perform queries against the channel graph. If
|
||||||
// the graph cache is not enabled, then the call-back will be provided with
|
// the graph cache is not enabled, then the call-back will be provided with
|
||||||
// access to the graph via a consistent read-only transaction.
|
// access to the graph via a consistent read-only transaction.
|
||||||
func (c *ChannelGraph) GraphSession(cb func(graph NodeTraverser) error) error {
|
func (c *ChannelGraph) GraphSession(cb func(graph NodeTraverser) error,
|
||||||
|
reset func()) error {
|
||||||
|
|
||||||
if c.graphCache != nil {
|
if c.graphCache != nil {
|
||||||
return cb(c)
|
return cb(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.V1Store.GraphSession(cb)
|
return c.V1Store.GraphSession(cb, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachNodeCached iterates through all the stored vertices/nodes in the
|
// ForEachNodeCached iterates through all the stored vertices/nodes in the
|
||||||
@@ -246,14 +249,14 @@ func (c *ChannelGraph) GraphSession(cb func(graph NodeTraverser) error) error {
|
|||||||
//
|
//
|
||||||
// NOTE: The callback contents MUST not be modified.
|
// NOTE: The callback contents MUST not be modified.
|
||||||
func (c *ChannelGraph) ForEachNodeCached(ctx context.Context,
|
func (c *ChannelGraph) ForEachNodeCached(ctx context.Context,
|
||||||
cb func(node route.Vertex,
|
cb func(node route.Vertex, chans map[uint64]*DirectedChannel) error,
|
||||||
chans map[uint64]*DirectedChannel) error) error {
|
reset func()) error {
|
||||||
|
|
||||||
if c.graphCache != nil {
|
if c.graphCache != nil {
|
||||||
return c.graphCache.ForEachNode(cb)
|
return c.graphCache.ForEachNode(cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.V1Store.ForEachNodeCached(ctx, cb)
|
return c.V1Store.ForEachNodeCached(ctx, cb, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddLightningNode adds a vertex/node to the graph database. If the node is not
|
// AddLightningNode adds a vertex/node to the graph database. If the node is not
|
||||||
|
|||||||
+34
-33
@@ -935,7 +935,8 @@ func TestEdgePolicyCRUD(t *testing.T) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {},
|
||||||
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1330,7 +1331,7 @@ func TestForEachSourceNodeChannel(t *testing.T) {
|
|||||||
delete(expectedSrcChans, chanPoint)
|
delete(expectedSrcChans, chanPoint)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Empty(t, expectedSrcChans)
|
require.Empty(t, expectedSrcChans)
|
||||||
}
|
}
|
||||||
@@ -1373,7 +1374,7 @@ func TestGraphTraversal(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Iterate through all the known channels within the graph DB, once
|
// Iterate through all the known channels within the graph DB, once
|
||||||
@@ -1385,7 +1386,7 @@ func TestGraphTraversal(t *testing.T) {
|
|||||||
|
|
||||||
delete(chanIndex, ei.ChannelID)
|
delete(chanIndex, ei.ChannelID)
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, chanIndex, 0)
|
require.Len(t, chanIndex, 0)
|
||||||
|
|
||||||
@@ -1393,7 +1394,8 @@ func TestGraphTraversal(t *testing.T) {
|
|||||||
// outgoing channels for a particular node.
|
// outgoing channels for a particular node.
|
||||||
numNodeChans := 0
|
numNodeChans := 0
|
||||||
firstNode, secondNode := nodeList[0], nodeList[1]
|
firstNode, secondNode := nodeList[0], nodeList[1]
|
||||||
err = graph.ForEachNodeChannel(ctx, firstNode.PubKeyBytes,
|
err = graph.ForEachNodeChannel(
|
||||||
|
ctx, firstNode.PubKeyBytes,
|
||||||
func(_ *models.ChannelEdgeInfo, outEdge,
|
func(_ *models.ChannelEdgeInfo, outEdge,
|
||||||
inEdge *models.ChannelEdgePolicy) error {
|
inEdge *models.ChannelEdgePolicy) error {
|
||||||
|
|
||||||
@@ -1424,7 +1426,8 @@ func TestGraphTraversal(t *testing.T) {
|
|||||||
numNodeChans++
|
numNodeChans++
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {},
|
||||||
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, numChannels, numNodeChans)
|
require.Equal(t, numChannels, numNodeChans)
|
||||||
}
|
}
|
||||||
@@ -1451,7 +1454,7 @@ func TestGraphTraversalCacheable(t *testing.T) {
|
|||||||
nodeMap[tx.Node().PubKeyBytes] = struct{}{}
|
nodeMap[tx.Node().PubKeyBytes] = struct{}{}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, nodeMap, numNodes)
|
require.Len(t, nodeMap, numNodes)
|
||||||
|
|
||||||
@@ -1466,6 +1469,8 @@ func TestGraphTraversalCacheable(t *testing.T) {
|
|||||||
nodes = append(nodes, node)
|
nodes = append(nodes, node)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
nodes = nil
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, nodeMap, 0)
|
require.Len(t, nodeMap, 0)
|
||||||
@@ -1485,7 +1490,7 @@ func TestGraphTraversalCacheable(t *testing.T) {
|
|||||||
node, func(d *DirectedChannel) error {
|
node, func(d *DirectedChannel) error {
|
||||||
delete(chanIndex, d.ChannelID)
|
delete(chanIndex, d.ChannelID)
|
||||||
return nil
|
return nil
|
||||||
},
|
}, func() {},
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -1494,7 +1499,7 @@ func TestGraphTraversalCacheable(t *testing.T) {
|
|||||||
node, func(d *DirectedChannel) error {
|
node, func(d *DirectedChannel) error {
|
||||||
delete(chanIndex2, d.ChannelID)
|
delete(chanIndex2, d.ChannelID)
|
||||||
return nil
|
return nil
|
||||||
},
|
}, func() {},
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
@@ -1580,7 +1585,7 @@ func fillTestGraph(t testing.TB, graph *ChannelGraph, numNodes,
|
|||||||
err := graph.ForEachNode(ctx, func(tx NodeRTx) error {
|
err := graph.ForEachNode(ctx, func(tx NodeRTx) error {
|
||||||
delete(nodeIndex, tx.Node().Alias)
|
delete(nodeIndex, tx.Node().Alias)
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, nodeIndex, 0)
|
require.Len(t, nodeIndex, 0)
|
||||||
|
|
||||||
@@ -1669,22 +1674,19 @@ func assertPruneTip(t *testing.T, graph *ChannelGraph,
|
|||||||
|
|
||||||
func assertNumChans(t *testing.T, graph *ChannelGraph, n int) {
|
func assertNumChans(t *testing.T, graph *ChannelGraph, n int) {
|
||||||
numChans := 0
|
numChans := 0
|
||||||
if err := graph.ForEachChannel(context.Background(),
|
err := graph.ForEachChannel(
|
||||||
func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
context.Background(), func(*models.ChannelEdgeInfo,
|
||||||
|
*models.ChannelEdgePolicy,
|
||||||
*models.ChannelEdgePolicy) error {
|
*models.ChannelEdgePolicy) error {
|
||||||
|
|
||||||
numChans++
|
numChans++
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
numChans = 0
|
||||||
},
|
},
|
||||||
); err != nil {
|
)
|
||||||
_, _, line, _ := runtime.Caller(1)
|
require.NoError(t, err)
|
||||||
t.Fatalf("line %v: unable to scan channels: %v", line, err)
|
require.Equal(t, n, numChans)
|
||||||
}
|
|
||||||
if numChans != n {
|
|
||||||
_, _, line, _ := runtime.Caller(1)
|
|
||||||
t.Fatalf("line %v: expected %v chans instead have %v", line,
|
|
||||||
n, numChans)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertNumNodes(t *testing.T, graph *ChannelGraph, n int) {
|
func assertNumNodes(t *testing.T, graph *ChannelGraph, n int) {
|
||||||
@@ -1693,7 +1695,7 @@ func assertNumNodes(t *testing.T, graph *ChannelGraph, n int) {
|
|||||||
numNodes++
|
numNodes++
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_, _, line, _ := runtime.Caller(1)
|
_, _, line, _ := runtime.Caller(1)
|
||||||
t.Fatalf("line %v: unable to scan nodes: %v", line, err)
|
t.Fatalf("line %v: unable to scan nodes: %v", line, err)
|
||||||
@@ -3146,7 +3148,8 @@ func TestIncompleteChannelPolicies(t *testing.T) {
|
|||||||
expectedOut bool) {
|
expectedOut bool) {
|
||||||
|
|
||||||
calls := 0
|
calls := 0
|
||||||
err := graph.ForEachNodeChannel(ctx, node.PubKeyBytes,
|
err := graph.ForEachNodeChannel(
|
||||||
|
ctx, node.PubKeyBytes,
|
||||||
func(_ *models.ChannelEdgeInfo, outEdge,
|
func(_ *models.ChannelEdgeInfo, outEdge,
|
||||||
inEdge *models.ChannelEdgePolicy) error {
|
inEdge *models.ChannelEdgePolicy) error {
|
||||||
|
|
||||||
@@ -3169,14 +3172,10 @@ func TestIncompleteChannelPolicies(t *testing.T) {
|
|||||||
calls++
|
calls++
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {},
|
||||||
if err != nil {
|
)
|
||||||
t.Fatalf("unable to scan channels: %v", err)
|
require.NoError(t, err)
|
||||||
}
|
require.Equal(t, 1, calls)
|
||||||
|
|
||||||
if calls != 1 {
|
|
||||||
t.Fatalf("Expected only one callback call")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checkPolicies(node2, false, false)
|
checkPolicies(node2, false, false)
|
||||||
@@ -4230,6 +4229,8 @@ func BenchmarkForEachChannel(b *testing.B) {
|
|||||||
nodes = append(nodes, node)
|
nodes = append(nodes, node)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
nodes = nil
|
||||||
})
|
})
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
|
|
||||||
@@ -4250,7 +4251,7 @@ func BenchmarkForEachChannel(b *testing.B) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err := graph.ForEachNodeChannel(ctx, n, cb)
|
err := graph.ForEachNodeChannel(ctx, n, cb, func() {})
|
||||||
require.NoError(b, err)
|
require.NoError(b, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4297,7 +4298,7 @@ func TestGraphCacheForEachNodeChannel(t *testing.T) {
|
|||||||
ch = c
|
ch = c
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
}, func() {},
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
|||||||
+13
-11
@@ -40,7 +40,7 @@ type NodeTraverser interface {
|
|||||||
// ForEachNodeDirectedChannel calls the callback for every channel of
|
// ForEachNodeDirectedChannel calls the callback for every channel of
|
||||||
// the given node.
|
// the given node.
|
||||||
ForEachNodeDirectedChannel(nodePub route.Vertex,
|
ForEachNodeDirectedChannel(nodePub route.Vertex,
|
||||||
cb func(channel *DirectedChannel) error) error
|
cb func(channel *DirectedChannel) error, reset func()) error
|
||||||
|
|
||||||
// FetchNodeFeatures returns the features of the given node.
|
// FetchNodeFeatures returns the features of the given node.
|
||||||
FetchNodeFeatures(nodePub route.Vertex) (*lnwire.FeatureVector, error)
|
FetchNodeFeatures(nodePub route.Vertex) (*lnwire.FeatureVector, error)
|
||||||
@@ -72,7 +72,8 @@ type V1Store interface { //nolint:interfacebloat
|
|||||||
// the channel and the channel peer's node information.
|
// the channel and the channel peer's node information.
|
||||||
ForEachSourceNodeChannel(ctx context.Context,
|
ForEachSourceNodeChannel(ctx context.Context,
|
||||||
cb func(chanPoint wire.OutPoint, havePolicy bool,
|
cb func(chanPoint wire.OutPoint, havePolicy bool,
|
||||||
otherNode *models.LightningNode) error) error
|
otherNode *models.LightningNode) error,
|
||||||
|
reset func()) error
|
||||||
|
|
||||||
// ForEachNodeChannel iterates through all channels of the given node,
|
// ForEachNodeChannel iterates through all channels of the given node,
|
||||||
// executing the passed callback with an edge info structure and the
|
// executing the passed callback with an edge info structure and the
|
||||||
@@ -85,14 +86,14 @@ type V1Store interface { //nolint:interfacebloat
|
|||||||
// Unknown policies are passed into the callback as nil values.
|
// Unknown policies are passed into the callback as nil values.
|
||||||
ForEachNodeChannel(ctx context.Context, nodePub route.Vertex,
|
ForEachNodeChannel(ctx context.Context, nodePub route.Vertex,
|
||||||
cb func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
cb func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
||||||
*models.ChannelEdgePolicy) error) error
|
*models.ChannelEdgePolicy) error, reset func()) error
|
||||||
|
|
||||||
// ForEachNodeCached is similar to forEachNode, but it returns
|
// ForEachNodeCached is similar to forEachNode, but it returns
|
||||||
// DirectedChannel data to the call-back.
|
// DirectedChannel data to the call-back.
|
||||||
//
|
//
|
||||||
// NOTE: The callback contents MUST not be modified.
|
// NOTE: The callback contents MUST not be modified.
|
||||||
ForEachNodeCached(ctx context.Context, cb func(node route.Vertex,
|
ForEachNodeCached(ctx context.Context, cb func(node route.Vertex,
|
||||||
chans map[uint64]*DirectedChannel) error) error
|
chans map[uint64]*DirectedChannel) error, reset func()) error
|
||||||
|
|
||||||
// ForEachNode iterates through all the stored vertices/nodes in the
|
// ForEachNode iterates through all the stored vertices/nodes in the
|
||||||
// graph, executing the passed callback with each node encountered. If
|
// graph, executing the passed callback with each node encountered. If
|
||||||
@@ -101,14 +102,15 @@ type V1Store interface { //nolint:interfacebloat
|
|||||||
// passed to the call-back are executed under the same read transaction
|
// passed to the call-back are executed under the same read transaction
|
||||||
// and so, methods on the NodeTx object _MUST_ only be called from
|
// and so, methods on the NodeTx object _MUST_ only be called from
|
||||||
// within the call-back.
|
// within the call-back.
|
||||||
ForEachNode(ctx context.Context, cb func(tx NodeRTx) error) error
|
ForEachNode(ctx context.Context, cb func(tx NodeRTx) error,
|
||||||
|
reset func()) error
|
||||||
|
|
||||||
// ForEachNodeCacheable iterates through all the stored vertices/nodes
|
// ForEachNodeCacheable iterates through all the stored vertices/nodes
|
||||||
// in the graph, executing the passed callback with each node
|
// in the graph, executing the passed callback with each node
|
||||||
// encountered. If the callback returns an error, then the transaction
|
// encountered. If the callback returns an error, then the transaction
|
||||||
// is aborted and the iteration stops early.
|
// is aborted and the iteration stops early.
|
||||||
ForEachNodeCacheable(ctx context.Context, cb func(route.Vertex,
|
ForEachNodeCacheable(ctx context.Context, cb func(route.Vertex,
|
||||||
*lnwire.FeatureVector) error) error
|
*lnwire.FeatureVector) error, reset func()) error
|
||||||
|
|
||||||
// LookupAlias attempts to return the alias as advertised by the target
|
// LookupAlias attempts to return the alias as advertised by the target
|
||||||
// node.
|
// node.
|
||||||
@@ -147,7 +149,7 @@ type V1Store interface { //nolint:interfacebloat
|
|||||||
// GraphSession will provide the call-back with access to a
|
// GraphSession will provide the call-back with access to a
|
||||||
// NodeTraverser instance which can be used to perform queries against
|
// NodeTraverser instance which can be used to perform queries against
|
||||||
// the channel graph.
|
// the channel graph.
|
||||||
GraphSession(cb func(graph NodeTraverser) error) error
|
GraphSession(cb func(graph NodeTraverser) error, reset func()) error
|
||||||
|
|
||||||
// ForEachChannel iterates through all the channel edges stored within
|
// ForEachChannel iterates through all the channel edges stored within
|
||||||
// the graph and invokes the passed callback for each edge. The callback
|
// the graph and invokes the passed callback for each edge. The callback
|
||||||
@@ -159,8 +161,8 @@ type V1Store interface { //nolint:interfacebloat
|
|||||||
// pointer for that particular channel edge routing policy will be
|
// pointer for that particular channel edge routing policy will be
|
||||||
// passed into the callback.
|
// passed into the callback.
|
||||||
ForEachChannel(ctx context.Context, cb func(*models.ChannelEdgeInfo,
|
ForEachChannel(ctx context.Context, cb func(*models.ChannelEdgeInfo,
|
||||||
*models.ChannelEdgePolicy,
|
*models.ChannelEdgePolicy, *models.ChannelEdgePolicy) error,
|
||||||
*models.ChannelEdgePolicy) error) error
|
reset func()) error
|
||||||
|
|
||||||
// ForEachChannelCacheable iterates through all the channel edges stored
|
// ForEachChannelCacheable iterates through all the channel edges stored
|
||||||
// within the graph and invokes the passed callback for each edge. The
|
// within the graph and invokes the passed callback for each edge. The
|
||||||
@@ -175,8 +177,8 @@ type V1Store interface { //nolint:interfacebloat
|
|||||||
// NOTE: this method is like ForEachChannel but fetches only the data
|
// NOTE: this method is like ForEachChannel but fetches only the data
|
||||||
// required for the graph cache.
|
// required for the graph cache.
|
||||||
ForEachChannelCacheable(cb func(*models.CachedEdgeInfo,
|
ForEachChannelCacheable(cb func(*models.CachedEdgeInfo,
|
||||||
*models.CachedEdgePolicy,
|
*models.CachedEdgePolicy, *models.CachedEdgePolicy) error,
|
||||||
*models.CachedEdgePolicy) error) error
|
reset func()) error
|
||||||
|
|
||||||
// DisabledChannelIDs returns the channel ids of disabled channels.
|
// DisabledChannelIDs returns the channel ids of disabled channels.
|
||||||
// A channel is disabled when two of the associated ChanelEdgePolicies
|
// A channel is disabled when two of the associated ChanelEdgePolicies
|
||||||
|
|||||||
+62
-36
@@ -406,9 +406,9 @@ func (c *KVStore) AddrsForNode(ctx context.Context,
|
|||||||
// callback.
|
// callback.
|
||||||
func (c *KVStore) ForEachChannel(_ context.Context,
|
func (c *KVStore) ForEachChannel(_ context.Context,
|
||||||
cb func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
cb func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
||||||
*models.ChannelEdgePolicy) error) error {
|
*models.ChannelEdgePolicy) error, reset func()) error {
|
||||||
|
|
||||||
return forEachChannel(c.db, cb)
|
return forEachChannel(c.db, cb, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// forEachChannel iterates through all the channel edges stored within the
|
// forEachChannel iterates through all the channel edges stored within the
|
||||||
@@ -421,7 +421,8 @@ func (c *KVStore) ForEachChannel(_ context.Context,
|
|||||||
// for that particular channel edge routing policy will be passed into the
|
// for that particular channel edge routing policy will be passed into the
|
||||||
// callback.
|
// callback.
|
||||||
func forEachChannel(db kvdb.Backend, cb func(*models.ChannelEdgeInfo,
|
func forEachChannel(db kvdb.Backend, cb func(*models.ChannelEdgeInfo,
|
||||||
*models.ChannelEdgePolicy, *models.ChannelEdgePolicy) error) error {
|
*models.ChannelEdgePolicy, *models.ChannelEdgePolicy) error,
|
||||||
|
reset func()) error {
|
||||||
|
|
||||||
return db.View(func(tx kvdb.RTx) error {
|
return db.View(func(tx kvdb.RTx) error {
|
||||||
edges := tx.ReadBucket(edgeBucket)
|
edges := tx.ReadBucket(edgeBucket)
|
||||||
@@ -469,7 +470,7 @@ func forEachChannel(db kvdb.Backend, cb func(*models.ChannelEdgeInfo,
|
|||||||
return cb(&info, policy1, policy2)
|
return cb(&info, policy1, policy2)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}, func() {})
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachChannelCacheable iterates through all the channel edges stored within
|
// ForEachChannelCacheable iterates through all the channel edges stored within
|
||||||
@@ -485,7 +486,8 @@ func forEachChannel(db kvdb.Backend, cb func(*models.ChannelEdgeInfo,
|
|||||||
// NOTE: this method is like ForEachChannel but fetches only the data required
|
// NOTE: this method is like ForEachChannel but fetches only the data required
|
||||||
// for the graph cache.
|
// for the graph cache.
|
||||||
func (c *KVStore) ForEachChannelCacheable(cb func(*models.CachedEdgeInfo,
|
func (c *KVStore) ForEachChannelCacheable(cb func(*models.CachedEdgeInfo,
|
||||||
*models.CachedEdgePolicy, *models.CachedEdgePolicy) error) error {
|
*models.CachedEdgePolicy, *models.CachedEdgePolicy) error,
|
||||||
|
reset func()) error {
|
||||||
|
|
||||||
return c.db.View(func(tx kvdb.RTx) error {
|
return c.db.View(func(tx kvdb.RTx) error {
|
||||||
edges := tx.ReadBucket(edgeBucket)
|
edges := tx.ReadBucket(edgeBucket)
|
||||||
@@ -558,7 +560,7 @@ func (c *KVStore) ForEachChannelCacheable(cb func(*models.CachedEdgeInfo,
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}, func() {})
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// forEachNodeDirectedChannel iterates through all channels of a given node,
|
// forEachNodeDirectedChannel iterates through all channels of a given node,
|
||||||
@@ -568,8 +570,13 @@ func (c *KVStore) ForEachChannelCacheable(cb func(*models.CachedEdgeInfo,
|
|||||||
// transaction may be provided. If none is provided, a new one will be created.
|
// transaction may be provided. If none is provided, a new one will be created.
|
||||||
//
|
//
|
||||||
// Unknown policies are passed into the callback as nil values.
|
// Unknown policies are passed into the callback as nil values.
|
||||||
|
//
|
||||||
|
// NOTE: the reset param is only meaningful if the tx param is nil. If it is
|
||||||
|
// not nil, the caller is expected to have passed in a reset to the parent
|
||||||
|
// function's View/Update call which will then apply to the whole transaction.
|
||||||
func (c *KVStore) forEachNodeDirectedChannel(tx kvdb.RTx,
|
func (c *KVStore) forEachNodeDirectedChannel(tx kvdb.RTx,
|
||||||
node route.Vertex, cb func(channel *DirectedChannel) error) error {
|
node route.Vertex, cb func(channel *DirectedChannel) error,
|
||||||
|
reset func()) error {
|
||||||
|
|
||||||
// Fallback that uses the database.
|
// Fallback that uses the database.
|
||||||
toNodeCallback := func() route.Vertex {
|
toNodeCallback := func() route.Vertex {
|
||||||
@@ -612,7 +619,7 @@ func (c *KVStore) forEachNodeDirectedChannel(tx kvdb.RTx,
|
|||||||
return cb(directedChannel)
|
return cb(directedChannel)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodeTraversal(tx, node[:], c.db, dbCallback)
|
return nodeTraversal(tx, node[:], c.db, dbCallback, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetchNodeFeatures returns the features of a given node. If no features are
|
// fetchNodeFeatures returns the features of a given node. If no features are
|
||||||
@@ -648,9 +655,9 @@ func (c *KVStore) fetchNodeFeatures(tx kvdb.RTx,
|
|||||||
//
|
//
|
||||||
// NOTE: this is part of the graphdb.NodeTraverser interface.
|
// NOTE: this is part of the graphdb.NodeTraverser interface.
|
||||||
func (c *KVStore) ForEachNodeDirectedChannel(nodePub route.Vertex,
|
func (c *KVStore) ForEachNodeDirectedChannel(nodePub route.Vertex,
|
||||||
cb func(channel *DirectedChannel) error) error {
|
cb func(channel *DirectedChannel) error, reset func()) error {
|
||||||
|
|
||||||
return c.forEachNodeDirectedChannel(nil, nodePub, cb)
|
return c.forEachNodeDirectedChannel(nil, nodePub, cb, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchNodeFeatures returns the features of the given node. If no features are
|
// FetchNodeFeatures returns the features of the given node. If no features are
|
||||||
@@ -668,8 +675,8 @@ func (c *KVStore) FetchNodeFeatures(nodePub route.Vertex) (
|
|||||||
//
|
//
|
||||||
// NOTE: The callback contents MUST not be modified.
|
// NOTE: The callback contents MUST not be modified.
|
||||||
func (c *KVStore) ForEachNodeCached(_ context.Context,
|
func (c *KVStore) ForEachNodeCached(_ context.Context,
|
||||||
cb func(node route.Vertex,
|
cb func(node route.Vertex, chans map[uint64]*DirectedChannel) error,
|
||||||
chans map[uint64]*DirectedChannel) error) error {
|
reset func()) error {
|
||||||
|
|
||||||
// Otherwise call back to a version that uses the database directly.
|
// Otherwise call back to a version that uses the database directly.
|
||||||
// We'll iterate over each node, then the set of channels for each
|
// We'll iterate over each node, then the set of channels for each
|
||||||
@@ -723,13 +730,14 @@ func (c *KVStore) ForEachNodeCached(_ context.Context,
|
|||||||
channels[e.ChannelID] = directedChannel
|
channels[e.ChannelID] = directedChannel
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, reset,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return cb(node.PubKeyBytes, channels)
|
return cb(node.PubKeyBytes, channels)
|
||||||
})
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisabledChannelIDs returns the channel ids of disabled channels.
|
// DisabledChannelIDs returns the channel ids of disabled channels.
|
||||||
@@ -791,13 +799,13 @@ func (c *KVStore) DisabledChannelIDs() ([]uint64, error) {
|
|||||||
// executed under the same read transaction and so, methods on the NodeTx object
|
// executed under the same read transaction and so, methods on the NodeTx object
|
||||||
// _MUST_ only be called from within the call-back.
|
// _MUST_ only be called from within the call-back.
|
||||||
func (c *KVStore) ForEachNode(_ context.Context,
|
func (c *KVStore) ForEachNode(_ context.Context,
|
||||||
cb func(tx NodeRTx) error) error {
|
cb func(tx NodeRTx) error, reset func()) error {
|
||||||
|
|
||||||
return forEachNode(c.db, func(tx kvdb.RTx,
|
return forEachNode(c.db, func(tx kvdb.RTx,
|
||||||
node *models.LightningNode) error {
|
node *models.LightningNode) error {
|
||||||
|
|
||||||
return cb(newChanGraphNodeTx(tx, c, node))
|
return cb(newChanGraphNodeTx(tx, c, node))
|
||||||
})
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// forEachNode iterates through all the stored vertices/nodes in the graph,
|
// forEachNode iterates through all the stored vertices/nodes in the graph,
|
||||||
@@ -808,7 +816,7 @@ func (c *KVStore) ForEachNode(_ context.Context,
|
|||||||
// TODO(roasbeef): add iterator interface to allow for memory efficient graph
|
// TODO(roasbeef): add iterator interface to allow for memory efficient graph
|
||||||
// traversal when graph gets mega.
|
// traversal when graph gets mega.
|
||||||
func forEachNode(db kvdb.Backend,
|
func forEachNode(db kvdb.Backend,
|
||||||
cb func(kvdb.RTx, *models.LightningNode) error) error {
|
cb func(kvdb.RTx, *models.LightningNode) error, reset func()) error {
|
||||||
|
|
||||||
traversal := func(tx kvdb.RTx) error {
|
traversal := func(tx kvdb.RTx) error {
|
||||||
// First grab the nodes bucket which stores the mapping from
|
// First grab the nodes bucket which stores the mapping from
|
||||||
@@ -838,7 +846,7 @@ func forEachNode(db kvdb.Backend,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return kvdb.View(db, traversal, func() {})
|
return kvdb.View(db, traversal, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachNodeCacheable iterates through all the stored vertices/nodes in the
|
// ForEachNodeCacheable iterates through all the stored vertices/nodes in the
|
||||||
@@ -846,7 +854,8 @@ func forEachNode(db kvdb.Backend,
|
|||||||
// callback returns an error, then the transaction is aborted and the iteration
|
// callback returns an error, then the transaction is aborted and the iteration
|
||||||
// stops early.
|
// stops early.
|
||||||
func (c *KVStore) ForEachNodeCacheable(_ context.Context,
|
func (c *KVStore) ForEachNodeCacheable(_ context.Context,
|
||||||
cb func(route.Vertex, *lnwire.FeatureVector) error) error {
|
cb func(route.Vertex, *lnwire.FeatureVector) error,
|
||||||
|
reset func()) error {
|
||||||
|
|
||||||
traversal := func(tx kvdb.RTx) error {
|
traversal := func(tx kvdb.RTx) error {
|
||||||
// First grab the nodes bucket which stores the mapping from
|
// First grab the nodes bucket which stores the mapping from
|
||||||
@@ -878,7 +887,7 @@ func (c *KVStore) ForEachNodeCacheable(_ context.Context,
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return kvdb.View(c.db, traversal, func() {})
|
return kvdb.View(c.db, traversal, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SourceNode returns the source node of the graph. The source node is treated
|
// SourceNode returns the source node of the graph. The source node is treated
|
||||||
@@ -3018,6 +3027,8 @@ func (c *KVStore) isPublic(tx kvdb.RTx, nodePub route.Vertex,
|
|||||||
|
|
||||||
// Otherwise, we'll continue our search.
|
// Otherwise, we'll continue our search.
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
nodeIsPublic = false
|
||||||
})
|
})
|
||||||
if err != nil && !errors.Is(err, errDone) {
|
if err != nil && !errors.Is(err, errDone) {
|
||||||
return false, err
|
return false, err
|
||||||
@@ -3157,9 +3168,13 @@ func (c *KVStore) HasLightningNode(_ context.Context,
|
|||||||
|
|
||||||
// nodeTraversal is used to traverse all channels of a node given by its
|
// nodeTraversal is used to traverse all channels of a node given by its
|
||||||
// public key and passes channel information into the specified callback.
|
// public key and passes channel information into the specified callback.
|
||||||
|
//
|
||||||
|
// NOTE: the reset param is only meaningful if the tx param is nil. If it is
|
||||||
|
// not nil, the caller is expected to have passed in a reset to the parent
|
||||||
|
// function's View/Update call which will then apply to the whole transaction.
|
||||||
func nodeTraversal(tx kvdb.RTx, nodePub []byte, db kvdb.Backend,
|
func nodeTraversal(tx kvdb.RTx, nodePub []byte, db kvdb.Backend,
|
||||||
cb func(kvdb.RTx, *models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
cb func(kvdb.RTx, *models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
||||||
*models.ChannelEdgePolicy) error) error {
|
*models.ChannelEdgePolicy) error, reset func()) error {
|
||||||
|
|
||||||
traversal := func(tx kvdb.RTx) error {
|
traversal := func(tx kvdb.RTx) error {
|
||||||
edges := tx.ReadBucket(edgeBucket)
|
edges := tx.ReadBucket(edgeBucket)
|
||||||
@@ -3230,7 +3245,7 @@ func nodeTraversal(tx kvdb.RTx, nodePub []byte, db kvdb.Backend,
|
|||||||
// If no transaction was provided, then we'll create a new transaction
|
// If no transaction was provided, then we'll create a new transaction
|
||||||
// to execute the transaction within.
|
// to execute the transaction within.
|
||||||
if tx == nil {
|
if tx == nil {
|
||||||
return kvdb.View(db, traversal, func() {})
|
return kvdb.View(db, traversal, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, we re-use the existing transaction to execute the graph
|
// Otherwise, we re-use the existing transaction to execute the graph
|
||||||
@@ -3248,14 +3263,16 @@ func nodeTraversal(tx kvdb.RTx, nodePub []byte, db kvdb.Backend,
|
|||||||
// Unknown policies are passed into the callback as nil values.
|
// Unknown policies are passed into the callback as nil values.
|
||||||
func (c *KVStore) ForEachNodeChannel(_ context.Context, nodePub route.Vertex,
|
func (c *KVStore) ForEachNodeChannel(_ context.Context, nodePub route.Vertex,
|
||||||
cb func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
cb func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
||||||
*models.ChannelEdgePolicy) error) error {
|
*models.ChannelEdgePolicy) error, reset func()) error {
|
||||||
|
|
||||||
return nodeTraversal(nil, nodePub[:], c.db, func(_ kvdb.RTx,
|
return nodeTraversal(
|
||||||
|
nil, nodePub[:], c.db, func(_ kvdb.RTx,
|
||||||
info *models.ChannelEdgeInfo, policy,
|
info *models.ChannelEdgeInfo, policy,
|
||||||
policy2 *models.ChannelEdgePolicy) error {
|
policy2 *models.ChannelEdgePolicy) error {
|
||||||
|
|
||||||
return cb(info, policy, policy2)
|
return cb(info, policy, policy2)
|
||||||
})
|
}, reset,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachSourceNodeChannel iterates through all channels of the source node,
|
// ForEachSourceNodeChannel iterates through all channels of the source node,
|
||||||
@@ -3264,7 +3281,7 @@ func (c *KVStore) ForEachNodeChannel(_ context.Context, nodePub route.Vertex,
|
|||||||
// peer's node information.
|
// peer's node information.
|
||||||
func (c *KVStore) ForEachSourceNodeChannel(_ context.Context,
|
func (c *KVStore) ForEachSourceNodeChannel(_ context.Context,
|
||||||
cb func(chanPoint wire.OutPoint, havePolicy bool,
|
cb func(chanPoint wire.OutPoint, havePolicy bool,
|
||||||
otherNode *models.LightningNode) error) error {
|
otherNode *models.LightningNode) error, reset func()) error {
|
||||||
|
|
||||||
return kvdb.View(c.db, func(tx kvdb.RTx) error {
|
return kvdb.View(c.db, func(tx kvdb.RTx) error {
|
||||||
nodes := tx.ReadBucket(nodeBucket)
|
nodes := tx.ReadBucket(nodeBucket)
|
||||||
@@ -3292,9 +3309,9 @@ func (c *KVStore) ForEachSourceNodeChannel(_ context.Context,
|
|||||||
return cb(
|
return cb(
|
||||||
info.ChannelPoint, policy != nil, peer,
|
info.ChannelPoint, policy != nil, peer,
|
||||||
)
|
)
|
||||||
},
|
}, reset,
|
||||||
)
|
)
|
||||||
}, func() {})
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// forEachNodeChannelTx iterates through all channels of the given node,
|
// forEachNodeChannelTx iterates through all channels of the given node,
|
||||||
@@ -3310,12 +3327,14 @@ func (c *KVStore) ForEachSourceNodeChannel(_ context.Context,
|
|||||||
// should be passed as the first argument. Otherwise, the first argument should
|
// should be passed as the first argument. Otherwise, the first argument should
|
||||||
// be nil and a fresh transaction will be created to execute the graph
|
// be nil and a fresh transaction will be created to execute the graph
|
||||||
// traversal.
|
// traversal.
|
||||||
|
//
|
||||||
|
// NOTE: the reset function is only meaningful if the tx param is nil.
|
||||||
func (c *KVStore) forEachNodeChannelTx(tx kvdb.RTx,
|
func (c *KVStore) forEachNodeChannelTx(tx kvdb.RTx,
|
||||||
nodePub route.Vertex, cb func(kvdb.RTx, *models.ChannelEdgeInfo,
|
nodePub route.Vertex, cb func(kvdb.RTx, *models.ChannelEdgeInfo,
|
||||||
*models.ChannelEdgePolicy,
|
*models.ChannelEdgePolicy, *models.ChannelEdgePolicy) error,
|
||||||
*models.ChannelEdgePolicy) error) error {
|
reset func()) error {
|
||||||
|
|
||||||
return nodeTraversal(tx, nodePub[:], c.db, cb)
|
return nodeTraversal(tx, nodePub[:], c.db, cb, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fetchOtherNode attempts to fetch the full LightningNode that's opposite of
|
// fetchOtherNode attempts to fetch the full LightningNode that's opposite of
|
||||||
@@ -3955,13 +3974,15 @@ func (c *KVStore) IsClosedScid(scid lnwire.ShortChannelID) (bool, error) {
|
|||||||
|
|
||||||
// GraphSession will provide the call-back with access to a NodeTraverser
|
// GraphSession will provide the call-back with access to a NodeTraverser
|
||||||
// instance which can be used to perform queries against the channel graph.
|
// instance which can be used to perform queries against the channel graph.
|
||||||
func (c *KVStore) GraphSession(cb func(graph NodeTraverser) error) error {
|
func (c *KVStore) GraphSession(cb func(graph NodeTraverser) error,
|
||||||
|
reset func()) error {
|
||||||
|
|
||||||
return c.db.View(func(tx walletdb.ReadTx) error {
|
return c.db.View(func(tx walletdb.ReadTx) error {
|
||||||
return cb(&nodeTraverserSession{
|
return cb(&nodeTraverserSession{
|
||||||
db: c,
|
db: c,
|
||||||
tx: tx,
|
tx: tx,
|
||||||
})
|
})
|
||||||
}, func() {})
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nodeTraverserSession implements the NodeTraverser interface but with a
|
// nodeTraverserSession implements the NodeTraverser interface but with a
|
||||||
@@ -3976,9 +3997,9 @@ type nodeTraverserSession struct {
|
|||||||
//
|
//
|
||||||
// NOTE: Part of the NodeTraverser interface.
|
// NOTE: Part of the NodeTraverser interface.
|
||||||
func (c *nodeTraverserSession) ForEachNodeDirectedChannel(nodePub route.Vertex,
|
func (c *nodeTraverserSession) ForEachNodeDirectedChannel(nodePub route.Vertex,
|
||||||
cb func(channel *DirectedChannel) error) error {
|
cb func(channel *DirectedChannel) error, _ func()) error {
|
||||||
|
|
||||||
return c.db.forEachNodeDirectedChannel(c.tx, nodePub, cb)
|
return c.db.forEachNodeDirectedChannel(c.tx, nodePub, cb, func() {})
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchNodeFeatures returns the features of the given node. If the node is
|
// FetchNodeFeatures returns the features of the given node. If the node is
|
||||||
@@ -4902,11 +4923,16 @@ func (c *chanGraphNodeTx) FetchNode(nodePub route.Vertex) (NodeRTx, error) {
|
|||||||
func (c *chanGraphNodeTx) ForEachChannel(f func(*models.ChannelEdgeInfo,
|
func (c *chanGraphNodeTx) ForEachChannel(f func(*models.ChannelEdgeInfo,
|
||||||
*models.ChannelEdgePolicy, *models.ChannelEdgePolicy) error) error {
|
*models.ChannelEdgePolicy, *models.ChannelEdgePolicy) error) error {
|
||||||
|
|
||||||
return c.db.forEachNodeChannelTx(c.tx, c.node.PubKeyBytes,
|
return c.db.forEachNodeChannelTx(
|
||||||
|
c.tx, c.node.PubKeyBytes,
|
||||||
func(_ kvdb.RTx, info *models.ChannelEdgeInfo, policy1,
|
func(_ kvdb.RTx, info *models.ChannelEdgeInfo, policy1,
|
||||||
policy2 *models.ChannelEdgePolicy) error {
|
policy2 *models.ChannelEdgePolicy) error {
|
||||||
|
|
||||||
return f(info, policy1, policy2)
|
return f(info, policy1, policy2)
|
||||||
},
|
},
|
||||||
|
// NOTE: We don't need to reset anything here as the caller is
|
||||||
|
// expected to pass in the reset function to the ForEachNode
|
||||||
|
// method that constructed the chanGraphNodeTx.
|
||||||
|
func() {},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -206,6 +206,9 @@ func migrateNodes(ctx context.Context, kvBackend kvdb.Backend,
|
|||||||
return sqldb.CompareRecords(
|
return sqldb.CompareRecords(
|
||||||
node, migratedNode, fmt.Sprintf("node %x", pub),
|
node, migratedNode, fmt.Sprintf("node %x", pub),
|
||||||
)
|
)
|
||||||
|
}, func() {
|
||||||
|
// No reset is needed since if a retry occurs, the entire
|
||||||
|
// migration will be retried from the start.
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not migrate nodes: %w", err)
|
return fmt.Errorf("could not migrate nodes: %w", err)
|
||||||
@@ -384,6 +387,9 @@ func migrateChannelsAndPolicies(ctx context.Context, kvBackend kvdb.Backend,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
// No reset is needed since if a retry occurs, the entire
|
||||||
|
// migration will be retried from the start.
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not migrate channels and policies: %w",
|
return fmt.Errorf("could not migrate channels and policies: %w",
|
||||||
|
|||||||
@@ -401,6 +401,8 @@ func fetchAllNodes(t *testing.T, store V1Store) []*models.LightningNode {
|
|||||||
nodes = append(nodes, node)
|
nodes = append(nodes, node)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
nodes = nil
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@@ -475,7 +477,7 @@ func fetchAllChannelsAndPolicies(t *testing.T, store V1Store) chanSet {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Sort the channels by their channel ID to ensure a consistent order.
|
// Sort the channels by their channel ID to ensure a consistent order.
|
||||||
|
|||||||
+24
-21
@@ -727,7 +727,7 @@ func (s *SQLStore) updateEdgeCache(e *models.ChannelEdgePolicy,
|
|||||||
// NOTE: part of the V1Store interface.
|
// NOTE: part of the V1Store interface.
|
||||||
func (s *SQLStore) ForEachSourceNodeChannel(ctx context.Context,
|
func (s *SQLStore) ForEachSourceNodeChannel(ctx context.Context,
|
||||||
cb func(chanPoint wire.OutPoint, havePolicy bool,
|
cb func(chanPoint wire.OutPoint, havePolicy bool,
|
||||||
otherNode *models.LightningNode) error) error {
|
otherNode *models.LightningNode) error, reset func()) error {
|
||||||
|
|
||||||
return s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
return s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
||||||
nodeID, nodePub, err := s.getSourceNode(ctx, db, ProtocolV1)
|
nodeID, nodePub, err := s.getSourceNode(ctx, db, ProtocolV1)
|
||||||
@@ -773,7 +773,7 @@ func (s *SQLStore) ForEachSourceNodeChannel(ctx context.Context,
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}, sqldb.NoOpReset)
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachNode iterates through all the stored vertices/nodes in the graph,
|
// ForEachNode iterates through all the stored vertices/nodes in the graph,
|
||||||
@@ -785,7 +785,7 @@ func (s *SQLStore) ForEachSourceNodeChannel(ctx context.Context,
|
|||||||
//
|
//
|
||||||
// NOTE: part of the V1Store interface.
|
// NOTE: part of the V1Store interface.
|
||||||
func (s *SQLStore) ForEachNode(ctx context.Context,
|
func (s *SQLStore) ForEachNode(ctx context.Context,
|
||||||
cb func(tx NodeRTx) error) error {
|
cb func(tx NodeRTx) error, reset func()) error {
|
||||||
|
|
||||||
var lastID int64 = 0
|
var lastID int64 = 0
|
||||||
handleNode := func(db SQLQueries, dbNode sqlc.Node) error {
|
handleNode := func(db SQLQueries, dbNode sqlc.Node) error {
|
||||||
@@ -835,7 +835,7 @@ func (s *SQLStore) ForEachNode(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}, sqldb.NoOpReset)
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sqlGraphNodeTx is an implementation of the NodeRTx interface backed by the
|
// sqlGraphNodeTx is an implementation of the NodeRTx interface backed by the
|
||||||
@@ -907,13 +907,13 @@ func (s *sqlGraphNodeTx) FetchNode(nodePub route.Vertex) (NodeRTx, error) {
|
|||||||
//
|
//
|
||||||
// NOTE: this is part of the graphdb.NodeTraverser interface.
|
// NOTE: this is part of the graphdb.NodeTraverser interface.
|
||||||
func (s *SQLStore) ForEachNodeDirectedChannel(nodePub route.Vertex,
|
func (s *SQLStore) ForEachNodeDirectedChannel(nodePub route.Vertex,
|
||||||
cb func(channel *DirectedChannel) error) error {
|
cb func(channel *DirectedChannel) error, reset func()) error {
|
||||||
|
|
||||||
var ctx = context.TODO()
|
var ctx = context.TODO()
|
||||||
|
|
||||||
return s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
return s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
||||||
return forEachNodeDirectedChannel(ctx, db, nodePub, cb)
|
return forEachNodeDirectedChannel(ctx, db, nodePub, cb)
|
||||||
}, sqldb.NoOpReset)
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachNodeCacheable iterates through all the stored vertices/nodes in the
|
// ForEachNodeCacheable iterates through all the stored vertices/nodes in the
|
||||||
@@ -923,7 +923,8 @@ func (s *SQLStore) ForEachNodeDirectedChannel(nodePub route.Vertex,
|
|||||||
//
|
//
|
||||||
// NOTE: This is a part of the V1Store interface.
|
// NOTE: This is a part of the V1Store interface.
|
||||||
func (s *SQLStore) ForEachNodeCacheable(ctx context.Context,
|
func (s *SQLStore) ForEachNodeCacheable(ctx context.Context,
|
||||||
cb func(route.Vertex, *lnwire.FeatureVector) error) error {
|
cb func(route.Vertex, *lnwire.FeatureVector) error,
|
||||||
|
reset func()) error {
|
||||||
|
|
||||||
err := s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
err := s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
||||||
return forEachNodeCacheable(ctx, db, func(nodeID int64,
|
return forEachNodeCacheable(ctx, db, func(nodeID int64,
|
||||||
@@ -937,7 +938,7 @@ func (s *SQLStore) ForEachNodeCacheable(ctx context.Context,
|
|||||||
|
|
||||||
return cb(nodePub, features)
|
return cb(nodePub, features)
|
||||||
})
|
})
|
||||||
}, sqldb.NoOpReset)
|
}, reset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to fetch nodes: %w", err)
|
return fmt.Errorf("unable to fetch nodes: %w", err)
|
||||||
}
|
}
|
||||||
@@ -957,7 +958,7 @@ func (s *SQLStore) ForEachNodeCacheable(ctx context.Context,
|
|||||||
// NOTE: part of the V1Store interface.
|
// NOTE: part of the V1Store interface.
|
||||||
func (s *SQLStore) ForEachNodeChannel(ctx context.Context, nodePub route.Vertex,
|
func (s *SQLStore) ForEachNodeChannel(ctx context.Context, nodePub route.Vertex,
|
||||||
cb func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
cb func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
||||||
*models.ChannelEdgePolicy) error) error {
|
*models.ChannelEdgePolicy) error, reset func()) error {
|
||||||
|
|
||||||
return s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
return s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
||||||
dbNode, err := db.GetNodeByPubKey(
|
dbNode, err := db.GetNodeByPubKey(
|
||||||
@@ -975,7 +976,7 @@ func (s *SQLStore) ForEachNodeChannel(ctx context.Context, nodePub route.Vertex,
|
|||||||
return forEachNodeChannel(
|
return forEachNodeChannel(
|
||||||
ctx, db, s.cfg.ChainHash, dbNode.ID, cb,
|
ctx, db, s.cfg.ChainHash, dbNode.ID, cb,
|
||||||
)
|
)
|
||||||
}, sqldb.NoOpReset)
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChanUpdatesInHorizon returns all the known channel edges which have at least
|
// ChanUpdatesInHorizon returns all the known channel edges which have at least
|
||||||
@@ -1104,8 +1105,8 @@ func (s *SQLStore) ChanUpdatesInHorizon(startTime,
|
|||||||
//
|
//
|
||||||
// NOTE: part of the V1Store interface.
|
// NOTE: part of the V1Store interface.
|
||||||
func (s *SQLStore) ForEachNodeCached(ctx context.Context,
|
func (s *SQLStore) ForEachNodeCached(ctx context.Context,
|
||||||
cb func(node route.Vertex,
|
cb func(node route.Vertex, chans map[uint64]*DirectedChannel) error,
|
||||||
chans map[uint64]*DirectedChannel) error) error {
|
reset func()) error {
|
||||||
|
|
||||||
return s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
return s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
||||||
return forEachNodeCacheable(ctx, db, func(nodeID int64,
|
return forEachNodeCacheable(ctx, db, func(nodeID int64,
|
||||||
@@ -1218,7 +1219,7 @@ func (s *SQLStore) ForEachNodeCached(ctx context.Context,
|
|||||||
|
|
||||||
return cb(nodePub, channels)
|
return cb(nodePub, channels)
|
||||||
})
|
})
|
||||||
}, sqldb.NoOpReset)
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachChannelCacheable iterates through all the channel edges stored
|
// ForEachChannelCacheable iterates through all the channel edges stored
|
||||||
@@ -1234,8 +1235,8 @@ func (s *SQLStore) ForEachNodeCached(ctx context.Context,
|
|||||||
// NOTE: this method is like ForEachChannel but fetches only the data
|
// NOTE: this method is like ForEachChannel but fetches only the data
|
||||||
// required for the graph cache.
|
// required for the graph cache.
|
||||||
func (s *SQLStore) ForEachChannelCacheable(cb func(*models.CachedEdgeInfo,
|
func (s *SQLStore) ForEachChannelCacheable(cb func(*models.CachedEdgeInfo,
|
||||||
*models.CachedEdgePolicy,
|
*models.CachedEdgePolicy, *models.CachedEdgePolicy) error,
|
||||||
*models.CachedEdgePolicy) error) error {
|
reset func()) error {
|
||||||
|
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
|
||||||
@@ -1315,7 +1316,7 @@ func (s *SQLStore) ForEachChannelCacheable(cb func(*models.CachedEdgeInfo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}, sqldb.NoOpReset)
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachChannel iterates through all the channel edges stored within the
|
// ForEachChannel iterates through all the channel edges stored within the
|
||||||
@@ -1331,7 +1332,7 @@ func (s *SQLStore) ForEachChannelCacheable(cb func(*models.CachedEdgeInfo,
|
|||||||
// NOTE: part of the V1Store interface.
|
// NOTE: part of the V1Store interface.
|
||||||
func (s *SQLStore) ForEachChannel(ctx context.Context,
|
func (s *SQLStore) ForEachChannel(ctx context.Context,
|
||||||
cb func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
cb func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
||||||
*models.ChannelEdgePolicy) error) error {
|
*models.ChannelEdgePolicy) error, reset func()) error {
|
||||||
|
|
||||||
handleChannel := func(db SQLQueries,
|
handleChannel := func(db SQLQueries,
|
||||||
row sqlc.ListChannelsWithPoliciesPaginatedRow) error {
|
row sqlc.ListChannelsWithPoliciesPaginatedRow) error {
|
||||||
@@ -1406,7 +1407,7 @@ func (s *SQLStore) ForEachChannel(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}, sqldb.NoOpReset)
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FilterChannelRange returns the channel ID's of all known channels which were
|
// FilterChannelRange returns the channel ID's of all known channels which were
|
||||||
@@ -2754,12 +2755,14 @@ func (s *SQLStore) IsClosedScid(scid lnwire.ShortChannelID) (bool, error) {
|
|||||||
// instance which can be used to perform queries against the channel graph.
|
// instance which can be used to perform queries against the channel graph.
|
||||||
//
|
//
|
||||||
// NOTE: part of the V1Store interface.
|
// NOTE: part of the V1Store interface.
|
||||||
func (s *SQLStore) GraphSession(cb func(graph NodeTraverser) error) error {
|
func (s *SQLStore) GraphSession(cb func(graph NodeTraverser) error,
|
||||||
|
reset func()) error {
|
||||||
|
|
||||||
var ctx = context.TODO()
|
var ctx = context.TODO()
|
||||||
|
|
||||||
return s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
return s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error {
|
||||||
return cb(newSQLNodeTraverser(db, s.cfg.ChainHash))
|
return cb(newSQLNodeTraverser(db, s.cfg.ChainHash))
|
||||||
}, sqldb.NoOpReset)
|
}, reset)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sqlNodeTraverser implements the NodeTraverser interface but with a backing
|
// sqlNodeTraverser implements the NodeTraverser interface but with a backing
|
||||||
@@ -2788,7 +2791,7 @@ func newSQLNodeTraverser(db SQLQueries,
|
|||||||
//
|
//
|
||||||
// NOTE: Part of the NodeTraverser interface.
|
// NOTE: Part of the NodeTraverser interface.
|
||||||
func (s *sqlNodeTraverser) ForEachNodeDirectedChannel(nodePub route.Vertex,
|
func (s *sqlNodeTraverser) ForEachNodeDirectedChannel(nodePub route.Vertex,
|
||||||
cb func(channel *DirectedChannel) error) error {
|
cb func(channel *DirectedChannel) error, _ func()) error {
|
||||||
|
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -72,7 +72,7 @@ type ChannelGraphSource interface {
|
|||||||
// star-graph.
|
// star-graph.
|
||||||
ForAllOutgoingChannels(ctx context.Context,
|
ForAllOutgoingChannels(ctx context.Context,
|
||||||
cb func(c *models.ChannelEdgeInfo,
|
cb func(c *models.ChannelEdgeInfo,
|
||||||
e *models.ChannelEdgePolicy) error) error
|
e *models.ChannelEdgePolicy) error, reset func()) error
|
||||||
|
|
||||||
// CurrentBlockHeight returns the block height from POV of the router
|
// CurrentBlockHeight returns the block height from POV of the router
|
||||||
// subsystem.
|
// subsystem.
|
||||||
@@ -260,7 +260,7 @@ type DB interface {
|
|||||||
// Unknown policies are passed into the callback as nil values.
|
// Unknown policies are passed into the callback as nil values.
|
||||||
ForEachNodeChannel(ctx context.Context, nodePub route.Vertex,
|
ForEachNodeChannel(ctx context.Context, nodePub route.Vertex,
|
||||||
cb func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
cb func(*models.ChannelEdgeInfo, *models.ChannelEdgePolicy,
|
||||||
*models.ChannelEdgePolicy) error) error
|
*models.ChannelEdgePolicy) error, reset func()) error
|
||||||
|
|
||||||
// AddEdgeProof sets the proof of an existing edge in the graph
|
// AddEdgeProof sets the proof of an existing edge in the graph
|
||||||
// database.
|
// database.
|
||||||
|
|||||||
@@ -82,6 +82,9 @@ func testGraphMigration(ht *lntest.HarnessTest) {
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
}, func() {
|
||||||
|
clear(edges)
|
||||||
|
numNodes = 0
|
||||||
})
|
})
|
||||||
require.NoError(ht, err)
|
require.NoError(ht, err)
|
||||||
require.Equal(ht, expNumNodes, numNodes)
|
require.Equal(ht, expNumNodes, numNodes)
|
||||||
|
|||||||
@@ -63,16 +63,18 @@ func newBandwidthManager(graph Graph, sourceNode route.Vertex,
|
|||||||
|
|
||||||
// First, we'll collect the set of outbound edges from the target
|
// First, we'll collect the set of outbound edges from the target
|
||||||
// source node and add them to our bandwidth manager's map of channels.
|
// source node and add them to our bandwidth manager's map of channels.
|
||||||
err := graph.ForEachNodeDirectedChannel(sourceNode,
|
err := graph.ForEachNodeDirectedChannel(
|
||||||
func(channel *graphdb.DirectedChannel) error {
|
sourceNode, func(channel *graphdb.DirectedChannel) error {
|
||||||
shortID := lnwire.NewShortChanIDFromInt(
|
shortID := lnwire.NewShortChanIDFromInt(
|
||||||
channel.ChannelID,
|
channel.ChannelID,
|
||||||
)
|
)
|
||||||
manager.localChans[shortID] = struct{}{}
|
manager.localChans[shortID] = struct{}{}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
}, func() {
|
||||||
|
clear(manager.localChans)
|
||||||
|
},
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -15,7 +15,8 @@ type Graph interface {
|
|||||||
// ForEachNodeDirectedChannel calls the callback for every channel of
|
// ForEachNodeDirectedChannel calls the callback for every channel of
|
||||||
// the given node.
|
// the given node.
|
||||||
ForEachNodeDirectedChannel(nodePub route.Vertex,
|
ForEachNodeDirectedChannel(nodePub route.Vertex,
|
||||||
cb func(channel *graphdb.DirectedChannel) error) error
|
cb func(channel *graphdb.DirectedChannel) error,
|
||||||
|
reset func()) error
|
||||||
|
|
||||||
// FetchNodeFeatures returns the features of the given node.
|
// FetchNodeFeatures returns the features of the given node.
|
||||||
FetchNodeFeatures(nodePub route.Vertex) (*lnwire.FeatureVector, error)
|
FetchNodeFeatures(nodePub route.Vertex) (*lnwire.FeatureVector, error)
|
||||||
@@ -29,7 +30,8 @@ type GraphSessionFactory interface {
|
|||||||
// GraphSession will provide the call-back with access to a
|
// GraphSession will provide the call-back with access to a
|
||||||
// graphdb.NodeTraverser instance which can be used to perform queries
|
// graphdb.NodeTraverser instance which can be used to perform queries
|
||||||
// against the channel graph.
|
// against the channel graph.
|
||||||
GraphSession(cb func(graph graphdb.NodeTraverser) error) error
|
GraphSession(cb func(graph graphdb.NodeTraverser) error,
|
||||||
|
reset func()) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchAmountPairCapacity determines the maximal public capacity between two
|
// FetchAmountPairCapacity determines the maximal public capacity between two
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ type Manager struct {
|
|||||||
// channels. The ChannelEdgePolicy parameter may be nil.
|
// channels. The ChannelEdgePolicy parameter may be nil.
|
||||||
ForAllOutgoingChannels func(ctx context.Context,
|
ForAllOutgoingChannels func(ctx context.Context,
|
||||||
cb func(*models.ChannelEdgeInfo,
|
cb func(*models.ChannelEdgeInfo,
|
||||||
*models.ChannelEdgePolicy) error) error
|
*models.ChannelEdgePolicy) error, reset func()) error
|
||||||
|
|
||||||
// FetchChannel is used to query local channel parameters. Optionally an
|
// FetchChannel is used to query local channel parameters. Optionally an
|
||||||
// existing db tx can be supplied.
|
// existing db tx can be supplied.
|
||||||
@@ -152,7 +152,14 @@ func (r *Manager) UpdatePolicy(ctx context.Context,
|
|||||||
// Next, we'll loop over all the outgoing channels the router knows of.
|
// Next, we'll loop over all the outgoing channels the router knows of.
|
||||||
// If we have a filter then we'll only collect those channels, otherwise
|
// If we have a filter then we'll only collect those channels, otherwise
|
||||||
// we'll collect them all.
|
// we'll collect them all.
|
||||||
err := r.ForAllOutgoingChannels(ctx, processChan)
|
err := r.ForAllOutgoingChannels(
|
||||||
|
ctx, processChan,
|
||||||
|
func() {
|
||||||
|
failedUpdates = nil
|
||||||
|
edgesToUpdate = nil
|
||||||
|
clear(policiesToUpdate)
|
||||||
|
},
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ func TestManager(t *testing.T) {
|
|||||||
|
|
||||||
forAllOutgoingChannels := func(_ context.Context,
|
forAllOutgoingChannels := func(_ context.Context,
|
||||||
cb func(*models.ChannelEdgeInfo,
|
cb func(*models.ChannelEdgeInfo,
|
||||||
*models.ChannelEdgePolicy) error) error {
|
*models.ChannelEdgePolicy) error, _ func()) error {
|
||||||
|
|
||||||
for _, c := range channelSet {
|
for _, c := range channelSet {
|
||||||
if err := cb(c.edgeInfo, ¤tPolicy); err != nil {
|
if err := cb(c.edgeInfo, ¤tPolicy); err != nil {
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ func (m *mockGraph) addChannel(id uint64, node1id, node2id byte,
|
|||||||
//
|
//
|
||||||
// NOTE: Part of the Graph interface.
|
// NOTE: Part of the Graph interface.
|
||||||
func (m *mockGraph) ForEachNodeDirectedChannel(nodePub route.Vertex,
|
func (m *mockGraph) ForEachNodeDirectedChannel(nodePub route.Vertex,
|
||||||
cb func(channel *graphdb.DirectedChannel) error) error {
|
cb func(channel *graphdb.DirectedChannel) error, _ func()) error {
|
||||||
|
|
||||||
// Look up the mock node.
|
// Look up the mock node.
|
||||||
node, ok := m.nodes[nodePub]
|
node, ok := m.nodes[nodePub]
|
||||||
@@ -232,8 +232,8 @@ func (m *mockGraph) FetchNodeFeatures(nodePub route.Vertex) (
|
|||||||
// the channel graph.
|
// the channel graph.
|
||||||
//
|
//
|
||||||
// NOTE: Part of the GraphSessionFactory interface.
|
// NOTE: Part of the GraphSessionFactory interface.
|
||||||
func (m *mockGraph) GraphSession(
|
func (m *mockGraph) GraphSession(cb func(graph graphdb.NodeTraverser) error,
|
||||||
cb func(graph graphdb.NodeTraverser) error) error {
|
_ func()) error {
|
||||||
|
|
||||||
return cb(m)
|
return cb(m)
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-6
@@ -576,7 +576,12 @@ func getOutgoingBalance(node route.Vertex, outgoingChans map[uint64]struct{},
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over all channels of the to node.
|
// Iterate over all channels of the to node.
|
||||||
err := g.ForEachNodeDirectedChannel(node, cb)
|
err := g.ForEachNodeDirectedChannel(
|
||||||
|
node, cb, func() {
|
||||||
|
max = 0
|
||||||
|
total = 0
|
||||||
|
},
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, 0, err
|
||||||
}
|
}
|
||||||
@@ -1276,7 +1281,12 @@ func findBlindedPaths(g Graph, target route.Vertex,
|
|||||||
// it later on when we call "processNodeForBlindedPath".
|
// it later on when we call "processNodeForBlindedPath".
|
||||||
visited[nextTarget] = true
|
visited[nextTarget] = true
|
||||||
|
|
||||||
err := g.ForEachNodeDirectedChannel(nextTarget,
|
var (
|
||||||
|
incomingPathReset []blindedHop
|
||||||
|
nextTargetReset = nextTarget
|
||||||
|
)
|
||||||
|
err := g.ForEachNodeDirectedChannel(
|
||||||
|
nextTarget,
|
||||||
func(channel *graphdb.DirectedChannel) error {
|
func(channel *graphdb.DirectedChannel) error {
|
||||||
// This is not the right channel, continue to
|
// This is not the right channel, continue to
|
||||||
// the node's other channels.
|
// the node's other channels.
|
||||||
@@ -1286,18 +1296,21 @@ func findBlindedPaths(g Graph, target route.Vertex,
|
|||||||
|
|
||||||
// We found the channel in question. Prepend it
|
// We found the channel in question. Prepend it
|
||||||
// to the incoming path.
|
// to the incoming path.
|
||||||
incomingPath = append([]blindedHop{
|
incomingPathReset = append([]blindedHop{
|
||||||
{
|
{
|
||||||
vertex: channel.OtherNode,
|
vertex: channel.OtherNode,
|
||||||
channelID: channel.ChannelID,
|
channelID: channel.ChannelID,
|
||||||
edgeCapacity: channel.Capacity,
|
edgeCapacity: channel.Capacity,
|
||||||
},
|
},
|
||||||
}, incomingPath...)
|
}, incomingPathReset...)
|
||||||
|
|
||||||
// Update the target node.
|
// Update the target node.
|
||||||
nextTarget = channel.OtherNode
|
nextTargetReset = channel.OtherNode
|
||||||
|
|
||||||
return errChanFound
|
return errChanFound
|
||||||
|
}, func() {
|
||||||
|
incomingPathReset = nil
|
||||||
|
nextTargetReset = nextTarget
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
// We expect errChanFound to be returned if the channel in
|
// We expect errChanFound to be returned if the channel in
|
||||||
@@ -1308,6 +1321,8 @@ func findBlindedPaths(g Graph, target route.Vertex,
|
|||||||
return nil, fmt.Errorf("incoming channel %d is not "+
|
return nil, fmt.Errorf("incoming channel %d is not "+
|
||||||
"seen as owned by node %v", chanID, nextTarget)
|
"seen as owned by node %v", chanID, nextTarget)
|
||||||
}
|
}
|
||||||
|
nextTarget = nextTargetReset
|
||||||
|
incomingPath = append(incomingPathReset, incomingPath...)
|
||||||
|
|
||||||
// Check that the user didn't accidentally add a channel that
|
// Check that the user didn't accidentally add a channel that
|
||||||
// is owned by a node in the node omission set.
|
// is owned by a node in the node omission set.
|
||||||
@@ -1445,7 +1460,8 @@ func processNodeForBlindedPath(g Graph, node route.Vertex,
|
|||||||
|
|
||||||
// Now, iterate over the node's channels in search for paths to this
|
// Now, iterate over the node's channels in search for paths to this
|
||||||
// node that can be used for blinded paths
|
// node that can be used for blinded paths
|
||||||
err = g.ForEachNodeDirectedChannel(node,
|
err = g.ForEachNodeDirectedChannel(
|
||||||
|
node,
|
||||||
func(channel *graphdb.DirectedChannel) error {
|
func(channel *graphdb.DirectedChannel) error {
|
||||||
// Keep track of how many incoming channels this node
|
// Keep track of how many incoming channels this node
|
||||||
// has. We only use a node as an introduction node if it
|
// has. We only use a node as an introduction node if it
|
||||||
@@ -1488,6 +1504,9 @@ func processNodeForBlindedPath(g Graph, node route.Vertex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
hopSets = nil
|
||||||
|
chanCount = 0
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -3303,6 +3303,8 @@ func dbFindPath(graph *graphdb.ChannelGraph,
|
|||||||
)
|
)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
}, func() {
|
||||||
|
route = nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -343,7 +343,11 @@ func (p *paymentSession) RequestRoute(maxAmt, feeLimit lnwire.MilliSatoshi,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
err := p.graphSessFactory.GraphSession(findPath)
|
err := p.graphSessFactory.GraphSession(
|
||||||
|
findPath, func() {
|
||||||
|
path = nil
|
||||||
|
},
|
||||||
|
)
|
||||||
// If there is an error, and it is not a path finding error, we
|
// If there is an error, and it is not a path finding error, we
|
||||||
// return it immediately.
|
// return it immediately.
|
||||||
if err != nil && !lnutils.ErrorAs[*pathFindingError](err) {
|
if err != nil && !lnutils.ErrorAs[*pathFindingError](err) {
|
||||||
|
|||||||
@@ -259,8 +259,8 @@ func (g *sessionGraph) sourceNode() route.Vertex {
|
|||||||
return route.Vertex{}
|
return route.Vertex{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *sessionGraph) GraphSession(
|
func (g *sessionGraph) GraphSession(cb func(graph graphdb.NodeTraverser) error,
|
||||||
cb func(graph graphdb.NodeTraverser) error) error {
|
_ func()) error {
|
||||||
|
|
||||||
return cb(g)
|
return cb(g)
|
||||||
}
|
}
|
||||||
@@ -97,6 +97,7 @@ func (u *nodeEdgeUnifier) addPolicy(fromNode route.Vertex,
|
|||||||
// addGraphPolicies adds all policies that are known for the toNode in the
|
// addGraphPolicies adds all policies that are known for the toNode in the
|
||||||
// graph.
|
// graph.
|
||||||
func (u *nodeEdgeUnifier) addGraphPolicies(g Graph) error {
|
func (u *nodeEdgeUnifier) addGraphPolicies(g Graph) error {
|
||||||
|
var channels []*graphdb.DirectedChannel
|
||||||
cb := func(channel *graphdb.DirectedChannel) error {
|
cb := func(channel *graphdb.DirectedChannel) error {
|
||||||
// If there is no edge policy for this candidate node, skip.
|
// If there is no edge policy for this candidate node, skip.
|
||||||
// Note that we are searching backwards so this node would have
|
// Note that we are searching backwards so this node would have
|
||||||
@@ -108,6 +109,22 @@ func (u *nodeEdgeUnifier) addGraphPolicies(g Graph) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
channels = append(channels, channel)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over all channels of the to node.
|
||||||
|
err := g.ForEachNodeDirectedChannel(
|
||||||
|
u.toNode, cb, func() {
|
||||||
|
channels = nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, channel := range channels {
|
||||||
// Add this policy to the corresponding edgeUnifier. We default
|
// Add this policy to the corresponding edgeUnifier. We default
|
||||||
// to the clear hop payload size function because
|
// to the clear hop payload size function because
|
||||||
// `addGraphPolicies` is only used for cleartext intermediate
|
// `addGraphPolicies` is only used for cleartext intermediate
|
||||||
@@ -120,12 +137,9 @@ func (u *nodeEdgeUnifier) addGraphPolicies(g Graph) error {
|
|||||||
channel.OtherNode, channel.InPolicy, inboundFee,
|
channel.OtherNode, channel.InPolicy, inboundFee,
|
||||||
channel.Capacity, defaultHopPayloadSize, nil,
|
channel.Capacity, defaultHopPayloadSize, nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over all channels of the to node.
|
return nil
|
||||||
return g.ForEachNodeDirectedChannel(u.toNode, cb)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// unifiedEdge is the individual channel data that is kept inside an edgeUnifier
|
// unifiedEdge is the individual channel data that is kept inside an edgeUnifier
|
||||||
|
|||||||
+23
-2
@@ -6745,6 +6745,8 @@ func (r *rpcServer) DescribeGraph(ctx context.Context,
|
|||||||
resp.Nodes = append(resp.Nodes, lnNode)
|
resp.Nodes = append(resp.Nodes, lnNode)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
resp.Nodes = nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -6768,6 +6770,8 @@ func (r *rpcServer) DescribeGraph(ctx context.Context,
|
|||||||
resp.Edges = append(resp.Edges, edge)
|
resp.Edges = append(resp.Edges, edge)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
resp.Edges = nil
|
||||||
})
|
})
|
||||||
if err != nil && !errors.Is(err, graphdb.ErrGraphNoEdgesFound) {
|
if err != nil && !errors.Is(err, graphdb.ErrGraphNoEdgesFound) {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -7046,7 +7050,8 @@ func (r *rpcServer) GetNodeInfo(ctx context.Context,
|
|||||||
channels []*lnrpc.ChannelEdge
|
channels []*lnrpc.ChannelEdge
|
||||||
)
|
)
|
||||||
|
|
||||||
err = graph.ForEachNodeChannel(ctx, node.PubKeyBytes,
|
err = graph.ForEachNodeChannel(
|
||||||
|
ctx, node.PubKeyBytes,
|
||||||
func(edge *models.ChannelEdgeInfo,
|
func(edge *models.ChannelEdgeInfo,
|
||||||
c1, c2 *models.ChannelEdgePolicy) error {
|
c1, c2 *models.ChannelEdgePolicy) error {
|
||||||
|
|
||||||
@@ -7072,6 +7077,10 @@ func (r *rpcServer) GetNodeInfo(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
numChannels = 0
|
||||||
|
totalCapacity = 0
|
||||||
|
channels = nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -7208,6 +7217,15 @@ func (r *rpcServer) GetNetworkInfo(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
numChannels = 0
|
||||||
|
numNodes = 0
|
||||||
|
maxChanOut = 0
|
||||||
|
totalNetworkCapacity = 0
|
||||||
|
minChannelSize = math.MaxInt64
|
||||||
|
maxChannelSize = 0
|
||||||
|
allChans = nil
|
||||||
|
clear(seenChans)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -7728,7 +7746,8 @@ func (r *rpcServer) FeeReport(ctx context.Context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var feeReports []*lnrpc.ChannelFeeReport
|
var feeReports []*lnrpc.ChannelFeeReport
|
||||||
err = channelGraph.ForEachNodeChannel(ctx, selfNode.PubKeyBytes,
|
err = channelGraph.ForEachNodeChannel(
|
||||||
|
ctx, selfNode.PubKeyBytes,
|
||||||
func(chanInfo *models.ChannelEdgeInfo,
|
func(chanInfo *models.ChannelEdgeInfo,
|
||||||
edgePolicy, _ *models.ChannelEdgePolicy) error {
|
edgePolicy, _ *models.ChannelEdgePolicy) error {
|
||||||
|
|
||||||
@@ -7766,6 +7785,8 @@ func (r *rpcServer) FeeReport(ctx context.Context,
|
|||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
}, func() {
|
||||||
|
feeReports = nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1254,7 +1254,8 @@ func newServer(ctx context.Context, cfg *Config, listenAddrs []net.Addr,
|
|||||||
DefaultRoutingPolicy: cc.RoutingPolicy,
|
DefaultRoutingPolicy: cc.RoutingPolicy,
|
||||||
ForAllOutgoingChannels: func(ctx context.Context,
|
ForAllOutgoingChannels: func(ctx context.Context,
|
||||||
cb func(*models.ChannelEdgeInfo,
|
cb func(*models.ChannelEdgeInfo,
|
||||||
*models.ChannelEdgePolicy) error) error {
|
*models.ChannelEdgePolicy) error,
|
||||||
|
reset func()) error {
|
||||||
|
|
||||||
return s.graphDB.ForEachNodeChannel(ctx, selfVertex,
|
return s.graphDB.ForEachNodeChannel(ctx, selfVertex,
|
||||||
func(c *models.ChannelEdgeInfo,
|
func(c *models.ChannelEdgeInfo,
|
||||||
@@ -1264,7 +1265,7 @@ func newServer(ctx context.Context, cfg *Config, listenAddrs []net.Addr,
|
|||||||
// NOTE: The invoked callback here may
|
// NOTE: The invoked callback here may
|
||||||
// receive a nil channel policy.
|
// receive a nil channel policy.
|
||||||
return cb(c, e)
|
return cb(c, e)
|
||||||
},
|
}, reset,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
PropagateChanPolicyUpdate: s.authGossiper.PropagateChanPolicyUpdate,
|
PropagateChanPolicyUpdate: s.authGossiper.PropagateChanPolicyUpdate,
|
||||||
@@ -3599,7 +3600,7 @@ func (s *server) establishPersistentConnections(ctx context.Context) error {
|
|||||||
// nodeAddrsMap stores the combination of node public keys and addresses
|
// nodeAddrsMap stores the combination of node public keys and addresses
|
||||||
// that we'll attempt to reconnect to. PubKey strings are used as keys
|
// that we'll attempt to reconnect to. PubKey strings are used as keys
|
||||||
// since other PubKey forms can't be compared.
|
// since other PubKey forms can't be compared.
|
||||||
nodeAddrsMap := map[string]*nodeAddresses{}
|
nodeAddrsMap := make(map[string]*nodeAddresses)
|
||||||
|
|
||||||
// Iterate through the list of LinkNodes to find addresses we should
|
// Iterate through the list of LinkNodes to find addresses we should
|
||||||
// attempt to connect to based on our set of previous connections. Set
|
// attempt to connect to based on our set of previous connections. Set
|
||||||
@@ -3623,6 +3624,7 @@ func (s *server) establishPersistentConnections(ctx context.Context) error {
|
|||||||
// that have been added via NodeAnnouncement messages.
|
// that have been added via NodeAnnouncement messages.
|
||||||
// TODO(roasbeef): instead iterate over link nodes and query graph for
|
// TODO(roasbeef): instead iterate over link nodes and query graph for
|
||||||
// each of the nodes.
|
// each of the nodes.
|
||||||
|
graphAddrs := make(map[string]*nodeAddresses)
|
||||||
forEachSrcNodeChan := func(chanPoint wire.OutPoint,
|
forEachSrcNodeChan := func(chanPoint wire.OutPoint,
|
||||||
havePolicy bool, channelPeer *models.LightningNode) error {
|
havePolicy bool, channelPeer *models.LightningNode) error {
|
||||||
|
|
||||||
@@ -3688,10 +3690,14 @@ func (s *server) establishPersistentConnections(ctx context.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeAddrsMap[pubStr] = n
|
graphAddrs[pubStr] = n
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err = s.graphDB.ForEachSourceNodeChannel(ctx, forEachSrcNodeChan)
|
err = s.graphDB.ForEachSourceNodeChannel(
|
||||||
|
ctx, forEachSrcNodeChan, func() {
|
||||||
|
clear(graphAddrs)
|
||||||
|
},
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
srvrLog.Errorf("Failed to iterate over source node channels: "+
|
srvrLog.Errorf("Failed to iterate over source node channels: "+
|
||||||
"%v", err)
|
"%v", err)
|
||||||
@@ -3703,6 +3709,11 @@ func (s *server) establishPersistentConnections(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Combine the addresses from the link nodes and the channel graph.
|
||||||
|
for pubStr, nodeAddr := range graphAddrs {
|
||||||
|
nodeAddrsMap[pubStr] = nodeAddr
|
||||||
|
}
|
||||||
|
|
||||||
srvrLog.Debugf("Establishing %v persistent connections on start",
|
srvrLog.Debugf("Establishing %v persistent connections on start",
|
||||||
len(nodeAddrsMap))
|
len(nodeAddrsMap))
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user