graph+autopilot: let autopilot use new graph ForEachNode method
Which passes a NodeRTx to the call-back instead of a `kvdb.RTx`.
This commit is contained in:
6 files changed
+95
-66
No files matched your search
+31
-48
@@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/btcsuite/btcd/btcutil"
|
"github.com/btcsuite/btcd/btcutil"
|
||||||
graphdb "github.com/lightningnetwork/lnd/graph/db"
|
graphdb "github.com/lightningnetwork/lnd/graph/db"
|
||||||
"github.com/lightningnetwork/lnd/graph/db/models"
|
"github.com/lightningnetwork/lnd/graph/db/models"
|
||||||
"github.com/lightningnetwork/lnd/kvdb"
|
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
"github.com/lightningnetwork/lnd/routing/route"
|
"github.com/lightningnetwork/lnd/routing/route"
|
||||||
)
|
)
|
||||||
@@ -51,11 +50,7 @@ func ChannelGraphFromDatabase(db *graphdb.ChannelGraph) ChannelGraph {
|
|||||||
// channeldb.LightningNode. The wrapper method implement the autopilot.Node
|
// channeldb.LightningNode. The wrapper method implement the autopilot.Node
|
||||||
// interface.
|
// interface.
|
||||||
type dbNode struct {
|
type dbNode struct {
|
||||||
db *graphdb.ChannelGraph
|
tx graphdb.NodeRTx
|
||||||
|
|
||||||
tx kvdb.RTx
|
|
||||||
|
|
||||||
node *models.LightningNode
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A compile time assertion to ensure dbNode meets the autopilot.Node
|
// A compile time assertion to ensure dbNode meets the autopilot.Node
|
||||||
@@ -68,7 +63,7 @@ var _ Node = (*dbNode)(nil)
|
|||||||
//
|
//
|
||||||
// NOTE: Part of the autopilot.Node interface.
|
// NOTE: Part of the autopilot.Node interface.
|
||||||
func (d *dbNode) PubKey() [33]byte {
|
func (d *dbNode) PubKey() [33]byte {
|
||||||
return d.node.PubKeyBytes
|
return d.tx.Node().PubKeyBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Addrs returns a slice of publicly reachable public TCP addresses that the
|
// Addrs returns a slice of publicly reachable public TCP addresses that the
|
||||||
@@ -76,7 +71,7 @@ func (d *dbNode) PubKey() [33]byte {
|
|||||||
//
|
//
|
||||||
// NOTE: Part of the autopilot.Node interface.
|
// NOTE: Part of the autopilot.Node interface.
|
||||||
func (d *dbNode) Addrs() []net.Addr {
|
func (d *dbNode) Addrs() []net.Addr {
|
||||||
return d.node.Addresses
|
return d.tx.Node().Addresses
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachChannel is a higher-order function that will be used to iterate
|
// ForEachChannel is a higher-order function that will be used to iterate
|
||||||
@@ -86,43 +81,35 @@ func (d *dbNode) Addrs() []net.Addr {
|
|||||||
//
|
//
|
||||||
// NOTE: Part of the autopilot.Node interface.
|
// NOTE: Part of the autopilot.Node interface.
|
||||||
func (d *dbNode) ForEachChannel(cb func(ChannelEdge) error) error {
|
func (d *dbNode) ForEachChannel(cb func(ChannelEdge) error) error {
|
||||||
return d.db.ForEachNodeChannelTx(d.tx, d.node.PubKeyBytes,
|
return d.tx.ForEachChannel(func(ei *models.ChannelEdgeInfo, ep,
|
||||||
func(tx kvdb.RTx, ei *models.ChannelEdgeInfo, ep,
|
_ *models.ChannelEdgePolicy) error {
|
||||||
_ *models.ChannelEdgePolicy) error {
|
|
||||||
|
|
||||||
// Skip channels for which no outgoing edge policy is
|
// Skip channels for which no outgoing edge policy is available.
|
||||||
// available.
|
//
|
||||||
//
|
// TODO(joostjager): Ideally the case where channels have a nil
|
||||||
// TODO(joostjager): Ideally the case where channels
|
// policy should be supported, as autopilot is not looking at
|
||||||
// have a nil policy should be supported, as autopilot
|
// the policies. For now, it is not easily possible to get a
|
||||||
// is not looking at the policies. For now, it is not
|
// reference to the other end LightningNode object without
|
||||||
// easily possible to get a reference to the other end
|
// retrieving the policy.
|
||||||
// LightningNode object without retrieving the policy.
|
if ep == nil {
|
||||||
if ep == nil {
|
return nil
|
||||||
return nil
|
}
|
||||||
}
|
|
||||||
|
|
||||||
node, err := d.db.FetchLightningNodeTx(
|
node, err := d.tx.FetchNode(ep.ToNode)
|
||||||
tx, ep.ToNode,
|
if err != nil {
|
||||||
)
|
return err
|
||||||
if err != nil {
|
}
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
edge := ChannelEdge{
|
edge := ChannelEdge{
|
||||||
ChanID: lnwire.NewShortChanIDFromInt(
|
ChanID: lnwire.NewShortChanIDFromInt(ep.ChannelID),
|
||||||
ep.ChannelID,
|
Capacity: ei.Capacity,
|
||||||
),
|
Peer: &dbNode{
|
||||||
Capacity: ei.Capacity,
|
tx: node,
|
||||||
Peer: &dbNode{
|
},
|
||||||
tx: tx,
|
}
|
||||||
db: d.db,
|
|
||||||
node: node,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return cb(edge)
|
return cb(edge)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachNode is a higher-order function that should be called once for each
|
// ForEachNode is a higher-order function that should be called once for each
|
||||||
@@ -131,20 +118,16 @@ func (d *dbNode) ForEachChannel(cb func(ChannelEdge) error) error {
|
|||||||
//
|
//
|
||||||
// NOTE: Part of the autopilot.ChannelGraph interface.
|
// NOTE: Part of the autopilot.ChannelGraph interface.
|
||||||
func (d *databaseChannelGraph) ForEachNode(cb func(Node) error) error {
|
func (d *databaseChannelGraph) ForEachNode(cb func(Node) error) error {
|
||||||
return d.db.ForEachNode(func(tx kvdb.RTx,
|
return d.db.ForEachNode(func(nodeTx graphdb.NodeRTx) error {
|
||||||
n *models.LightningNode) 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
|
||||||
// addresses. As we won't be able to reach them to actually
|
// addresses. As we won't be able to reach them to actually
|
||||||
// open any channels.
|
// open any channels.
|
||||||
if len(n.Addresses) == 0 {
|
if len(nodeTx.Node().Addresses) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
node := &dbNode{
|
node := &dbNode{
|
||||||
db: d.db,
|
tx: nodeTx,
|
||||||
tx: tx,
|
|
||||||
node: n,
|
|
||||||
}
|
}
|
||||||
return cb(node)
|
return cb(node)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -514,18 +514,18 @@ func (d *testDBGraph) addRandChannel(node1, node2 *btcec.PublicKey,
|
|||||||
return &ChannelEdge{
|
return &ChannelEdge{
|
||||||
ChanID: chanID,
|
ChanID: chanID,
|
||||||
Capacity: capacity,
|
Capacity: capacity,
|
||||||
Peer: &dbNode{
|
Peer: &dbNode{tx: &testNodeTx{
|
||||||
db: d.db,
|
db: d,
|
||||||
node: vertex1,
|
node: vertex1,
|
||||||
},
|
}},
|
||||||
},
|
},
|
||||||
&ChannelEdge{
|
&ChannelEdge{
|
||||||
ChanID: chanID,
|
ChanID: chanID,
|
||||||
Capacity: capacity,
|
Capacity: capacity,
|
||||||
Peer: &dbNode{
|
Peer: &dbNode{tx: &testNodeTx{
|
||||||
db: d.db,
|
db: d,
|
||||||
node: vertex2,
|
node: vertex2,
|
||||||
},
|
}},
|
||||||
},
|
},
|
||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
@@ -702,3 +702,37 @@ func (m *memChannelGraph) addRandNode() (*btcec.PublicKey, error) {
|
|||||||
|
|
||||||
return newPub, nil
|
return newPub, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type testNodeTx struct {
|
||||||
|
db *testDBGraph
|
||||||
|
node *models.LightningNode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *testNodeTx) Node() *models.LightningNode {
|
||||||
|
return t.node
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *testNodeTx) ForEachChannel(f func(*models.ChannelEdgeInfo,
|
||||||
|
*models.ChannelEdgePolicy, *models.ChannelEdgePolicy) error) error {
|
||||||
|
|
||||||
|
return t.db.db.ForEachNodeChannel(t.node.PubKeyBytes, func(_ kvdb.RTx,
|
||||||
|
edge *models.ChannelEdgeInfo, policy1,
|
||||||
|
policy2 *models.ChannelEdgePolicy) error {
|
||||||
|
|
||||||
|
return f(edge, policy1, policy2)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *testNodeTx) FetchNode(pub route.Vertex) (graphdb.NodeRTx, error) {
|
||||||
|
node, err := t.db.db.FetchLightningNode(pub)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &testNodeTx{
|
||||||
|
db: t.db,
|
||||||
|
node: node,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ graphdb.NodeRTx = (*testNodeTx)(nil)
|
||||||
+18
-4
@@ -588,9 +588,9 @@ func (c *ChannelGraph) FetchNodeFeatures(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachNodeCached is similar to ForEachNode, but it utilizes the channel
|
// ForEachNodeCached is similar to forEachNode, but it utilizes the channel
|
||||||
// graph cache instead. Note that this doesn't return all the information the
|
// graph cache instead. Note that this doesn't return all the information the
|
||||||
// regular ForEachNode method does.
|
// regular forEachNode method does.
|
||||||
//
|
//
|
||||||
// NOTE: The callback contents MUST not be modified.
|
// NOTE: The callback contents MUST not be modified.
|
||||||
func (c *ChannelGraph) ForEachNodeCached(cb func(node route.Vertex,
|
func (c *ChannelGraph) ForEachNodeCached(cb func(node route.Vertex,
|
||||||
@@ -604,7 +604,7 @@ func (c *ChannelGraph) ForEachNodeCached(cb func(node route.Vertex,
|
|||||||
// 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
|
||||||
// node, and construct a similar callback functiopn signature as the
|
// node, and construct a similar callback functiopn signature as the
|
||||||
// main funcotin expects.
|
// main funcotin expects.
|
||||||
return c.ForEachNode(func(tx kvdb.RTx,
|
return c.forEachNode(func(tx kvdb.RTx,
|
||||||
node *models.LightningNode) error {
|
node *models.LightningNode) error {
|
||||||
|
|
||||||
channels := make(map[uint64]*DirectedChannel)
|
channels := make(map[uint64]*DirectedChannel)
|
||||||
@@ -716,11 +716,25 @@ func (c *ChannelGraph) DisabledChannelIDs() ([]uint64, error) {
|
|||||||
// ForEachNode iterates through all the stored vertices/nodes in the graph,
|
// ForEachNode iterates through all the stored vertices/nodes in the graph,
|
||||||
// executing the passed callback with each node encountered. If the callback
|
// executing the passed callback with each node encountered. If the callback
|
||||||
// returns an error, then the transaction is aborted and the iteration stops
|
// returns an error, then the transaction is aborted and the iteration stops
|
||||||
|
// early. Any operations performed on the NodeTx passed to the call-back are
|
||||||
|
// executed under the same read transaction and so, methods on the NodeTx object
|
||||||
|
// _MUST_ only be called from within the call-back.
|
||||||
|
func (c *ChannelGraph) ForEachNode(cb func(tx NodeRTx) error) error {
|
||||||
|
return c.forEachNode(func(tx kvdb.RTx,
|
||||||
|
node *models.LightningNode) error {
|
||||||
|
|
||||||
|
return cb(newChanGraphNodeTx(tx, c, node))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// forEachNode iterates through all the stored vertices/nodes in the graph,
|
||||||
|
// executing the passed callback with each node encountered. If the callback
|
||||||
|
// returns an error, then the transaction is aborted and the iteration stops
|
||||||
// early.
|
// early.
|
||||||
//
|
//
|
||||||
// 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 (c *ChannelGraph) ForEachNode(
|
func (c *ChannelGraph) forEachNode(
|
||||||
cb func(kvdb.RTx, *models.LightningNode) error) error {
|
cb func(kvdb.RTx, *models.LightningNode) error) error {
|
||||||
|
|
||||||
traversal := func(tx kvdb.RTx) error {
|
traversal := func(tx kvdb.RTx) error {
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ func TestGraphCacheAddNode(t *testing.T) {
|
|||||||
assertCachedPolicyEqual(t, outPolicy1, toChannels[0].InPolicy)
|
assertCachedPolicyEqual(t, outPolicy1, toChannels[0].InPolicy)
|
||||||
|
|
||||||
// Now that we've inserted two nodes into the graph, check that
|
// Now that we've inserted two nodes into the graph, check that
|
||||||
// we'll recover the same set of channels during ForEachNode.
|
// we'll recover the same set of channels during forEachNode.
|
||||||
nodes := make(map[route.Vertex]struct{})
|
nodes := make(map[route.Vertex]struct{})
|
||||||
chans := make(map[uint64]struct{})
|
chans := make(map[uint64]struct{})
|
||||||
_ = cache.ForEachNode(func(node route.Vertex,
|
_ = cache.ForEachNode(func(node route.Vertex,
|
||||||
|
|||||||
@@ -1092,7 +1092,7 @@ func TestGraphTraversalCacheable(t *testing.T) {
|
|||||||
// Create a map of all nodes with the iteration we know works (because
|
// Create a map of all nodes with the iteration we know works (because
|
||||||
// it is tested in another test).
|
// it is tested in another test).
|
||||||
nodeMap := make(map[route.Vertex]struct{})
|
nodeMap := make(map[route.Vertex]struct{})
|
||||||
err = graph.ForEachNode(
|
err = graph.forEachNode(
|
||||||
func(tx kvdb.RTx, n *models.LightningNode) error {
|
func(tx kvdb.RTx, n *models.LightningNode) error {
|
||||||
nodeMap[n.PubKeyBytes] = struct{}{}
|
nodeMap[n.PubKeyBytes] = struct{}{}
|
||||||
|
|
||||||
@@ -1217,7 +1217,7 @@ func fillTestGraph(t require.TestingT, graph *ChannelGraph, numNodes,
|
|||||||
|
|
||||||
// Iterate over each node as returned by the graph, if all nodes are
|
// Iterate over each node as returned by the graph, if all nodes are
|
||||||
// reached, then the map created above should be empty.
|
// reached, then the map created above should be empty.
|
||||||
err := graph.ForEachNode(
|
err := graph.forEachNode(
|
||||||
func(_ kvdb.RTx, node *models.LightningNode) error {
|
func(_ kvdb.RTx, node *models.LightningNode) error {
|
||||||
delete(nodeIndex, node.Alias)
|
delete(nodeIndex, node.Alias)
|
||||||
return nil
|
return nil
|
||||||
@@ -1329,7 +1329,7 @@ func assertNumChans(t *testing.T, graph *ChannelGraph, n int) {
|
|||||||
|
|
||||||
func assertNumNodes(t *testing.T, graph *ChannelGraph, n int) {
|
func assertNumNodes(t *testing.T, graph *ChannelGraph, n int) {
|
||||||
numNodes := 0
|
numNodes := 0
|
||||||
err := graph.ForEachNode(
|
err := graph.forEachNode(
|
||||||
func(_ kvdb.RTx, _ *models.LightningNode) error {
|
func(_ kvdb.RTx, _ *models.LightningNode) error {
|
||||||
numNodes++
|
numNodes++
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
+2
-4
@@ -6533,10 +6533,8 @@ func (r *rpcServer) DescribeGraph(ctx context.Context,
|
|||||||
// First iterate through all the known nodes (connected or unconnected
|
// First iterate through all the known nodes (connected or unconnected
|
||||||
// within the graph), collating their current state into the RPC
|
// within the graph), collating their current state into the RPC
|
||||||
// response.
|
// response.
|
||||||
err := graph.ForEachNode(func(_ kvdb.RTx,
|
err := graph.ForEachNode(func(nodeTx graphdb.NodeRTx) error {
|
||||||
node *models.LightningNode) error {
|
lnNode := marshalNode(nodeTx.Node())
|
||||||
|
|
||||||
lnNode := marshalNode(node)
|
|
||||||
|
|
||||||
resp.Nodes = append(resp.Nodes, lnNode)
|
resp.Nodes = append(resp.Nodes, lnNode)
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user