mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 09:53:54 +01:00
990dda4b18
Pass htlc amount down to the channel so that we don't need to rely on minHtlc (and pad it when the channel sets a 0 min htlc). Update test to just check some sane values since we're no longer relying on minHtlc amount at all.
114 lines
3.9 KiB
Go
114 lines
3.9 KiB
Go
package routing
|
|
|
|
import (
|
|
"github.com/lightningnetwork/lnd/channeldb"
|
|
"github.com/lightningnetwork/lnd/htlcswitch"
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
"github.com/lightningnetwork/lnd/routing/route"
|
|
)
|
|
|
|
// bandwidthHints provides hints about the currently available balance in our
|
|
// channels.
|
|
type bandwidthHints interface {
|
|
// availableChanBandwidth returns the total available bandwidth for a
|
|
// channel and a bool indicating whether the channel hint was found.
|
|
// The amount parameter is used to validate the outgoing htlc amount
|
|
// that we wish to add to the channel against its flow restrictions. If
|
|
// a zero amount is provided, the minimum htlc value for the channel
|
|
// will be used. If the channel is unavailable, a zero amount is
|
|
// returned.
|
|
availableChanBandwidth(channelID uint64,
|
|
amount lnwire.MilliSatoshi) (lnwire.MilliSatoshi, bool)
|
|
}
|
|
|
|
// getLinkQuery is the function signature used to lookup a link.
|
|
type getLinkQuery func(lnwire.ShortChannelID) (
|
|
htlcswitch.ChannelLink, error)
|
|
|
|
// bandwidthManager is an implementation of the bandwidthHints interface which
|
|
// uses the link lookup provided to query the link for our latest local channel
|
|
// balances.
|
|
type bandwidthManager struct {
|
|
getLink getLinkQuery
|
|
localChans map[lnwire.ShortChannelID]struct{}
|
|
}
|
|
|
|
// newBandwidthManager creates a bandwidth manager for the source node provided
|
|
// which is used to obtain hints from the lower layer w.r.t the available
|
|
// bandwidth of edges on the network. Currently, we'll only obtain bandwidth
|
|
// hints for the edges we directly have open ourselves. Obtaining these hints
|
|
// allows us to reduce the number of extraneous attempts as we can skip channels
|
|
// that are inactive, or just don't have enough bandwidth to carry the payment.
|
|
func newBandwidthManager(graph routingGraph, sourceNode route.Vertex,
|
|
linkQuery getLinkQuery) (*bandwidthManager, error) {
|
|
|
|
manager := &bandwidthManager{
|
|
getLink: linkQuery,
|
|
localChans: make(map[lnwire.ShortChannelID]struct{}),
|
|
}
|
|
|
|
// First, we'll collect the set of outbound edges from the target
|
|
// source node and add them to our bandwidth manager's map of channels.
|
|
err := graph.forEachNodeChannel(sourceNode,
|
|
func(channel *channeldb.DirectedChannel) error {
|
|
shortID := lnwire.NewShortChanIDFromInt(
|
|
channel.ChannelID,
|
|
)
|
|
manager.localChans[shortID] = struct{}{}
|
|
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return manager, nil
|
|
}
|
|
|
|
// getBandwidth queries the current state of a link and gets its currently
|
|
// available bandwidth. Note that this function assumes that the channel being
|
|
// queried is one of our local channels, so any failure to retrieve the link
|
|
// is interpreted as the link being offline.
|
|
func (b *bandwidthManager) getBandwidth(cid lnwire.ShortChannelID,
|
|
amount lnwire.MilliSatoshi) lnwire.MilliSatoshi {
|
|
link, err := b.getLink(cid)
|
|
if err != nil {
|
|
// If the link isn't online, then we'll report that it has
|
|
// zero bandwidth.
|
|
return 0
|
|
}
|
|
|
|
// If the link is found within the switch, but it isn't yet eligible
|
|
// to forward any HTLCs, then we'll treat it as if it isn't online in
|
|
// the first place.
|
|
if !link.EligibleToForward() {
|
|
return 0
|
|
}
|
|
|
|
// If our link isn't currently in a state where it can add another
|
|
// outgoing htlc, treat the link as unusable.
|
|
if err := link.MayAddOutgoingHtlc(amount); err != nil {
|
|
return 0
|
|
}
|
|
|
|
// Otherwise, we'll return the current best estimate for the available
|
|
// bandwidth for the link.
|
|
return link.Bandwidth()
|
|
}
|
|
|
|
// availableChanBandwidth returns the total available bandwidth for a channel
|
|
// and a bool indicating whether the channel hint was found. If the channel is
|
|
// unavailable, a zero amount is returned.
|
|
func (b *bandwidthManager) availableChanBandwidth(channelID uint64,
|
|
amount lnwire.MilliSatoshi) (lnwire.MilliSatoshi, bool) {
|
|
|
|
shortID := lnwire.NewShortChanIDFromInt(channelID)
|
|
_, ok := b.localChans[shortID]
|
|
if !ok {
|
|
return 0, false
|
|
}
|
|
|
|
return b.getBandwidth(shortID, amount), true
|
|
}
|