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

lightningnetwork / lnd / 17132206455

21 Aug 2025 03:56PM UTC coverage: 54.685% (-2.6%) from 57.321%
17132206455

Pull #10167

github

web-flow
Merge 5dd2ed093 into 0c2f045f5
Pull Request #10167: multi: bump Go to 1.24.6

4 of 31 new or added lines in 10 files covered. (12.9%)

23854 existing lines in 284 files now uncovered.

108937 of 199210 relevant lines covered (54.68%)

22026.48 hits per line

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

83.05
/routing/payment_session_source.go
1
package routing
2

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

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

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

26
        // SourceNode is the graph's source node.
27
        SourceNode *models.LightningNode
28

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

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

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

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

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

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

74
        return session, nil
12✔
75
}
76

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

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

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

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

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

136
                        edge := &PrivateEdge{
11✔
137
                                policy: edgePolicy,
11✔
138
                        }
11✔
139

11✔
140
                        v := route.NewVertex(hopHint.NodeID)
11✔
141
                        edges[v] = append(edges[v], edge)
11✔
142
                }
143
        }
144

145
        return edges, nil
29✔
146
}
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