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

lightningnetwork / lnd / 9915780197

13 Jul 2024 12:30AM UTC coverage: 49.268% (-9.1%) from 58.413%
9915780197

push

github

web-flow
Merge pull request #8653 from ProofOfKeags/fn-prim

DynComms [0/n]: `fn` package additions

92837 of 188433 relevant lines covered (49.27%)

1.55 hits per line

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

75.51
/routing/bandwidth.go
1
package routing
2

3
import (
4
        "github.com/lightningnetwork/lnd/channeldb"
5
        "github.com/lightningnetwork/lnd/htlcswitch"
6
        "github.com/lightningnetwork/lnd/lnwire"
7
        "github.com/lightningnetwork/lnd/routing/route"
8
)
9

10
// bandwidthHints provides hints about the currently available balance in our
11
// channels.
12
type bandwidthHints interface {
13
        // availableChanBandwidth returns the total available bandwidth for a
14
        // channel and a bool indicating whether the channel hint was found.
15
        // The amount parameter is used to validate the outgoing htlc amount
16
        // that we wish to add to the channel against its flow restrictions. If
17
        // a zero amount is provided, the minimum htlc value for the channel
18
        // will be used. If the channel is unavailable, a zero amount is
19
        // returned.
20
        availableChanBandwidth(channelID uint64,
21
                amount lnwire.MilliSatoshi) (lnwire.MilliSatoshi, bool)
22
}
23

24
// getLinkQuery is the function signature used to lookup a link.
25
type getLinkQuery func(lnwire.ShortChannelID) (
26
        htlcswitch.ChannelLink, error)
27

28
// bandwidthManager is an implementation of the bandwidthHints interface which
29
// uses the link lookup provided to query the link for our latest local channel
30
// balances.
31
type bandwidthManager struct {
32
        getLink    getLinkQuery
33
        localChans map[lnwire.ShortChannelID]struct{}
34
}
35

36
// newBandwidthManager creates a bandwidth manager for the source node provided
37
// which is used to obtain hints from the lower layer w.r.t the available
38
// bandwidth of edges on the network. Currently, we'll only obtain bandwidth
39
// hints for the edges we directly have open ourselves. Obtaining these hints
40
// allows us to reduce the number of extraneous attempts as we can skip channels
41
// that are inactive, or just don't have enough bandwidth to carry the payment.
42
func newBandwidthManager(graph routingGraph, sourceNode route.Vertex,
43
        linkQuery getLinkQuery) (*bandwidthManager, error) {
3✔
44

3✔
45
        manager := &bandwidthManager{
3✔
46
                getLink:    linkQuery,
3✔
47
                localChans: make(map[lnwire.ShortChannelID]struct{}),
3✔
48
        }
3✔
49

3✔
50
        // First, we'll collect the set of outbound edges from the target
3✔
51
        // source node and add them to our bandwidth manager's map of channels.
3✔
52
        err := graph.forEachNodeChannel(sourceNode,
3✔
53
                func(channel *channeldb.DirectedChannel) error {
6✔
54
                        shortID := lnwire.NewShortChanIDFromInt(
3✔
55
                                channel.ChannelID,
3✔
56
                        )
3✔
57
                        manager.localChans[shortID] = struct{}{}
3✔
58

3✔
59
                        return nil
3✔
60
                })
3✔
61

62
        if err != nil {
3✔
63
                return nil, err
×
64
        }
×
65

66
        return manager, nil
3✔
67
}
68

69
// getBandwidth queries the current state of a link and gets its currently
70
// available bandwidth. Note that this function assumes that the channel being
71
// queried is one of our local channels, so any failure to retrieve the link
72
// is interpreted as the link being offline.
73
func (b *bandwidthManager) getBandwidth(cid lnwire.ShortChannelID,
74
        amount lnwire.MilliSatoshi) lnwire.MilliSatoshi {
3✔
75

3✔
76
        link, err := b.getLink(cid)
3✔
77
        if err != nil {
3✔
78
                // If the link isn't online, then we'll report that it has
×
79
                // zero bandwidth.
×
80
                log.Warnf("ShortChannelID=%v: link not found: %v", cid, err)
×
81
                return 0
×
82
        }
×
83

84
        // If the link is found within the switch, but it isn't yet eligible
85
        // to forward any HTLCs, then we'll treat it as if it isn't online in
86
        // the first place.
87
        if !link.EligibleToForward() {
3✔
88
                log.Warnf("ShortChannelID=%v: not eligible to forward", cid)
×
89
                return 0
×
90
        }
×
91

92
        // If our link isn't currently in a state where it can  add another
93
        // outgoing htlc, treat the link as unusable.
94
        if err := link.MayAddOutgoingHtlc(amount); err != nil {
6✔
95
                log.Warnf("ShortChannelID=%v: cannot add outgoing htlc: %v",
3✔
96
                        cid, err)
3✔
97
                return 0
3✔
98
        }
3✔
99

100
        // Otherwise, we'll return the current best estimate for the available
101
        // bandwidth for the link.
102
        return link.Bandwidth()
3✔
103
}
104

105
// availableChanBandwidth returns the total available bandwidth for a channel
106
// and a bool indicating whether the channel hint was found. If the channel is
107
// unavailable, a zero amount is returned.
108
func (b *bandwidthManager) availableChanBandwidth(channelID uint64,
109
        amount lnwire.MilliSatoshi) (lnwire.MilliSatoshi, bool) {
3✔
110

3✔
111
        shortID := lnwire.NewShortChanIDFromInt(channelID)
3✔
112
        _, ok := b.localChans[shortID]
3✔
113
        if !ok {
3✔
114
                return 0, false
×
115
        }
×
116

117
        return b.getBandwidth(shortID, amount), true
3✔
118
}
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