@@ -403,16 +403,6 @@ func initChannelGraph(db kvdb.Backend) error {
403
403
return nil
404
404
}
405
405
406
- // NewPathFindTx returns a new read transaction that can be used for a single
407
- // path finding session. Will return nil if the graph cache is enabled.
408
- func (c * ChannelGraph ) NewPathFindTx () (kvdb.RTx , error ) {
409
- if c .graphCache != nil {
410
- return nil , nil
411
- }
412
-
413
- return c .db .BeginReadTx ()
414
- }
415
-
416
406
// AddrsForNode returns all known addresses for the target node public key that
417
407
// the graph DB is aware of. The returned boolean indicates if the given node is
418
408
// unknown to the graph DB or not.
@@ -500,13 +490,14 @@ func (c *ChannelGraph) ForEachChannel(cb func(*models.ChannelEdgeInfo,
500
490
}, func () {})
501
491
}
502
492
503
- // ForEachNodeDirectedChannel iterates through all channels of a given node,
493
+ // forEachNodeDirectedChannel iterates through all channels of a given node,
504
494
// executing the passed callback on the directed edge representing the channel
505
495
// and its incoming policy. If the callback returns an error, then the iteration
506
- // is halted with the error propagated back up to the caller.
496
+ // is halted with the error propagated back up to the caller. An optional read
497
+ // transaction may be provided. If none is provided, a new one will be created.
507
498
//
508
499
// Unknown policies are passed into the callback as nil values.
509
- func (c * ChannelGraph ) ForEachNodeDirectedChannel (tx kvdb.RTx ,
500
+ func (c * ChannelGraph ) forEachNodeDirectedChannel (tx kvdb.RTx ,
510
501
node route.Vertex , cb func (channel * DirectedChannel ) error ) error {
511
502
512
503
if c .graphCache != nil {
@@ -517,7 +508,7 @@ func (c *ChannelGraph) ForEachNodeDirectedChannel(tx kvdb.RTx,
517
508
toNodeCallback := func () route.Vertex {
518
509
return node
519
510
}
520
- toNodeFeatures , err := c .FetchNodeFeatures ( node )
511
+ toNodeFeatures , err := c .fetchNodeFeatures ( tx , node )
521
512
if err != nil {
522
513
return err
523
514
}
@@ -561,17 +552,18 @@ func (c *ChannelGraph) ForEachNodeDirectedChannel(tx kvdb.RTx,
561
552
return nodeTraversal (tx , node [:], c .db , dbCallback )
562
553
}
563
554
564
- // FetchNodeFeatures returns the features of a given node. If no features are
565
- // known for the node, an empty feature vector is returned.
566
- func (c * ChannelGraph ) FetchNodeFeatures (
555
+ // fetchNodeFeatures returns the features of a given node. If no features are
556
+ // known for the node, an empty feature vector is returned. An optional read
557
+ // transaction may be provided. If none is provided, a new one will be created.
558
+ func (c * ChannelGraph ) fetchNodeFeatures (tx kvdb.RTx ,
567
559
node route.Vertex ) (* lnwire.FeatureVector , error ) {
568
560
569
561
if c .graphCache != nil {
570
562
return c .graphCache .GetFeatures (node ), nil
571
563
}
572
564
573
565
// Fallback that uses the database.
574
- targetNode , err := c .FetchLightningNode ( node )
566
+ targetNode , err := c .FetchLightningNodeTx ( tx , node )
575
567
switch err {
576
568
// If the node exists and has features, return them directly.
577
569
case nil :
@@ -588,6 +580,34 @@ func (c *ChannelGraph) FetchNodeFeatures(
588
580
}
589
581
}
590
582
583
+ // ForEachNodeDirectedChannel iterates through all channels of a given node,
584
+ // executing the passed callback on the directed edge representing the channel
585
+ // and its incoming policy. If the callback returns an error, then the iteration
586
+ // is halted with the error propagated back up to the caller. If the graphCache
587
+ // is available, then it will be used to retrieve the node's channels instead
588
+ // of the database.
589
+ //
590
+ // Unknown policies are passed into the callback as nil values.
591
+ //
592
+ // NOTE: this is part of the graphdb.NodeTraverser interface.
593
+ func (c * ChannelGraph ) ForEachNodeDirectedChannel (nodePub route.Vertex ,
594
+ cb func (channel * DirectedChannel ) error ) error {
595
+
596
+ return c .forEachNodeDirectedChannel (nil , nodePub , cb )
597
+ }
598
+
599
+ // FetchNodeFeatures returns the features of the given node. If no features are
600
+ // known for the node, an empty feature vector is returned.
601
+ // If the graphCache is available, then it will be used to retrieve the node's
602
+ // features instead of the database.
603
+ //
604
+ // NOTE: this is part of the graphdb.NodeTraverser interface.
605
+ func (c * ChannelGraph ) FetchNodeFeatures (nodePub route.Vertex ) (
606
+ * lnwire.FeatureVector , error ) {
607
+
608
+ return c .fetchNodeFeatures (nil , nodePub )
609
+ }
610
+
591
611
// ForEachNodeCached is similar to forEachNode, but it utilizes the channel
592
612
// graph cache instead. Note that this doesn't return all the information the
593
613
// regular forEachNode method does.
@@ -617,8 +637,8 @@ func (c *ChannelGraph) ForEachNodeCached(cb func(node route.Vertex,
617
637
toNodeCallback := func () route.Vertex {
618
638
return node .PubKeyBytes
619
639
}
620
- toNodeFeatures , err := c .FetchNodeFeatures (
621
- node .PubKeyBytes ,
640
+ toNodeFeatures , err := c .fetchNodeFeatures (
641
+ tx , node .PubKeyBytes ,
622
642
)
623
643
if err != nil {
624
644
return err
@@ -3873,6 +3893,64 @@ func (c *ChannelGraph) IsClosedScid(scid lnwire.ShortChannelID) (bool, error) {
3873
3893
return isClosed , nil
3874
3894
}
3875
3895
3896
+ // GraphSession will provide the call-back with access to a NodeTraverser
3897
+ // instance which can be used to perform queries against the channel graph. If
3898
+ // the graph cache is not enabled, then the call-back will be provided with
3899
+ // access to the graph via a consistent read-only transaction.
3900
+ func (c * ChannelGraph ) GraphSession (cb func (graph NodeTraverser ) error ) error {
3901
+ var (
3902
+ tx kvdb.RTx
3903
+ err error
3904
+ commit = func () {}
3905
+ )
3906
+ if c .graphCache == nil {
3907
+ tx , err = c .db .BeginReadTx ()
3908
+ if err != nil {
3909
+ return err
3910
+ }
3911
+
3912
+ commit = func () {
3913
+ if err := tx .Rollback (); err != nil {
3914
+ log .Errorf ("Unable to rollback tx: %v" , err )
3915
+ }
3916
+ }
3917
+ }
3918
+ defer commit ()
3919
+
3920
+ return cb (& nodeTraverserSession {
3921
+ db : c ,
3922
+ tx : tx ,
3923
+ })
3924
+ }
3925
+
3926
+ // nodeTraverserSession implements the NodeTraverser interface but with a
3927
+ // backing read only transaction for a consistent view of the graph in the case
3928
+ // where the graph Cache has not been enabled.
3929
+ type nodeTraverserSession struct {
3930
+ tx kvdb.RTx
3931
+ db * ChannelGraph
3932
+ }
3933
+
3934
+ // ForEachNodeDirectedChannel calls the callback for every channel of the given
3935
+ // node.
3936
+ //
3937
+ // NOTE: Part of the NodeTraverser interface.
3938
+ func (c * nodeTraverserSession ) ForEachNodeDirectedChannel (nodePub route.Vertex ,
3939
+ cb func (channel * DirectedChannel ) error ) error {
3940
+
3941
+ return c .db .forEachNodeDirectedChannel (c .tx , nodePub , cb )
3942
+ }
3943
+
3944
+ // FetchNodeFeatures returns the features of the given node. If the node is
3945
+ // unknown, assume no additional features are supported.
3946
+ //
3947
+ // NOTE: Part of the NodeTraverser interface.
3948
+ func (c * nodeTraverserSession ) FetchNodeFeatures (nodePub route.Vertex ) (
3949
+ * lnwire.FeatureVector , error ) {
3950
+
3951
+ return c .db .fetchNodeFeatures (c .tx , nodePub )
3952
+ }
3953
+
3876
3954
func putLightningNode (nodeBucket kvdb.RwBucket , aliasBucket kvdb.RwBucket , // nolint:dupl
3877
3955
updateIndex kvdb.RwBucket , node * models.LightningNode ) error {
3878
3956
0 commit comments