• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 19924300449

04 Dec 2025 09:35AM UTC coverage: 53.479% (-1.9%) from 55.404%
19924300449

Pull #10419

github

web-flow
Merge f811805c6 into 20473482d
Pull Request #10419: [docs] Document use-native-sql=true for SQL migration step 2

110496 of 206616 relevant lines covered (53.48%)

21221.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.79
/routing/payment_session_source.go
1
package routing
2

3
import (
4
        "github.com/lightningnetwork/lnd/fn/v2"
5
        "github.com/lightningnetwork/lnd/graph/db/models"
6
        "github.com/lightningnetwork/lnd/htlcswitch"
7
        "github.com/lightningnetwork/lnd/lnwire"
8
        "github.com/lightningnetwork/lnd/routing/route"
9
        "github.com/lightningnetwork/lnd/tlv"
10
        "github.com/lightningnetwork/lnd/zpay32"
11
)
12

13
// A compile time assertion to ensure SessionSource meets the
14
// PaymentSessionSource interface.
15
var _ PaymentSessionSource = (*SessionSource)(nil)
16

17
// SessionSource defines a source for the router to retrieve new payment
18
// sessions.
19
type SessionSource struct {
20
        // GraphSessionFactory can be used to gain access to a Graph session.
21
        // If the backing DB allows it, this will mean that a read transaction
22
        // is being held during the use of the session.
23
        GraphSessionFactory GraphSessionFactory
24

25
        // SourceNode is the graph's source node.
26
        SourceNode *models.Node
27

28
        // GetLink is a method that allows querying the lower link layer
29
        // to determine the up to date available bandwidth at a prospective link
30
        // to be traversed. If the link isn't available, then a value of zero
31
        // should be returned. Otherwise, the current up to date knowledge of
32
        // the available bandwidth of the link should be returned.
33
        GetLink getLinkQuery
34

35
        // MissionControl is a shared memory of sorts that executions of payment
36
        // path finding use in order to remember which vertexes/edges were
37
        // pruned from prior attempts. During payment execution, errors sent by
38
        // nodes are mapped into a vertex or edge to be pruned. Each run will
39
        // then take into account this set of pruned vertexes/edges to reduce
40
        // route failure and pass on graph information gained to the next
41
        // execution.
42
        MissionControl MissionControlQuerier
43

44
        // PathFindingConfig defines global parameters that control the
45
        // trade-off in path finding between fees and probability.
46
        PathFindingConfig PathFindingConfig
47
}
48

49
// NewPaymentSession creates a new payment session backed by the latest prune
50
// view from Mission Control. An optional set of routing hints can be provided
51
// in order to populate additional edges to explore when finding a path to the
52
// payment's destination.
53
func (m *SessionSource) NewPaymentSession(p *LightningPayment,
54
        firstHopBlob fn.Option[tlv.Blob],
55
        trafficShaper fn.Option[htlcswitch.AuxTrafficShaper]) (PaymentSession,
56
        error) {
12✔
57

12✔
58
        getBandwidthHints := func(graph Graph) (bandwidthHints, error) {
36✔
59
                return newBandwidthManager(
24✔
60
                        graph, m.SourceNode.PubKeyBytes, m.GetLink,
24✔
61
                        firstHopBlob, trafficShaper,
24✔
62
                )
24✔
63
        }
24✔
64

65
        session, err := newPaymentSession(
12✔
66
                p, m.SourceNode.PubKeyBytes, getBandwidthHints,
12✔
67
                m.GraphSessionFactory, m.MissionControl, m.PathFindingConfig,
12✔
68
        )
12✔
69
        if err != nil {
12✔
70
                return nil, err
×
71
        }
×
72

73
        return session, nil
12✔
74
}
75

76
// NewPaymentSessionEmpty creates a new paymentSession instance that is empty,
77
// and will be exhausted immediately. Used for failure reporting to
78
// missioncontrol for resumed payment we don't want to make more attempts for.
79
func (m *SessionSource) NewPaymentSessionEmpty() PaymentSession {
×
80
        return &paymentSession{
×
81
                empty: true,
×
82
        }
×
83
}
×
84

85
// RouteHintsToEdges converts a list of invoice route hints to an edge map that
86
// can be passed into pathfinding.
87
func RouteHintsToEdges(routeHints [][]zpay32.HopHint, target route.Vertex) (
88
        map[route.Vertex][]AdditionalEdge, error) {
29✔
89

29✔
90
        edges := make(map[route.Vertex][]AdditionalEdge)
29✔
91

29✔
92
        // Traverse through all of the available hop hints and include them in
29✔
93
        // our edges map, indexed by the public key of the channel's starting
29✔
94
        // node.
29✔
95
        for _, routeHint := range routeHints {
40✔
96
                // If multiple hop hints are provided within a single route
11✔
97
                // hint, we'll assume they must be chained together and sorted
11✔
98
                // in forward order in order to reach the target successfully.
11✔
99
                for i, hopHint := range routeHint {
22✔
100
                        // In order to determine the end node of this hint,
11✔
101
                        // we'll need to look at the next hint's start node. If
11✔
102
                        // we've reached the end of the hints list, we can
11✔
103
                        // assume we've reached the destination.
11✔
104
                        endNode := target
11✔
105
                        if i != len(routeHint)-1 {
11✔
106
                                nodeID := routeHint[i+1].NodeID
×
107
                                copy(
×
108
                                        endNode[:],
×
109
                                        nodeID.SerializeCompressed(),
×
110
                                )
×
111
                        }
×
112

113
                        // Finally, create the channel edge from the hop hint
114
                        // and add it to list of edges corresponding to the node
115
                        // at the start of the channel.
116
                        edgePolicy := &models.CachedEdgePolicy{
11✔
117
                                ToNodePubKey: func() route.Vertex {
21✔
118
                                        return endNode
10✔
119
                                },
10✔
120
                                ToNodeFeatures: lnwire.EmptyFeatureVector(),
121
                                ChannelID:      hopHint.ChannelID,
122
                                FeeBaseMSat: lnwire.MilliSatoshi(
123
                                        hopHint.FeeBaseMSat,
124
                                ),
125
                                FeeProportionalMillionths: lnwire.MilliSatoshi(
126
                                        hopHint.FeeProportionalMillionths,
127
                                ),
128
                                TimeLockDelta: hopHint.CLTVExpiryDelta,
129
                        }
130

131
                        edge := &PrivateEdge{
11✔
132
                                policy: edgePolicy,
11✔
133
                        }
11✔
134

11✔
135
                        v := route.NewVertex(hopHint.NodeID)
11✔
136
                        edges[v] = append(edges[v], edge)
11✔
137
                }
138
        }
139

140
        return edges, nil
29✔
141
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc