htlcswitch+routing: return IsHandled from AuxBandwidth

To make it more clear whether the external traffic shaper is handling a
channel or not, we return an explicit boolean.
This commit is contained in:
Oliver Gugger 2025-02-11 17:16:06 +01:00
parent d10ab03b75
commit 716db8b7d3
No known key found for this signature in database
GPG key ID: 8E4256593F177720
5 changed files with 36 additions and 14 deletions

View file

@ -208,8 +208,18 @@ const (
// OptionalBandwidth is a type alias for the result of a bandwidth query that // OptionalBandwidth is a type alias for the result of a bandwidth query that
// may return a bandwidth value or fn.None if the bandwidth is not available or // may return a bandwidth value or fn.None if the bandwidth is not available or
// not applicable. // not applicable. IsHandled is set to false if the external traffic shaper does
type OptionalBandwidth = fn.Option[lnwire.MilliSatoshi] // not handle the channel in question.
type OptionalBandwidth struct {
// IsHandled is true if the external traffic shaper handles the channel.
// If this is false, then the bandwidth value is not applicable.
IsHandled bool
// Bandwidth is the available bandwidth for the channel, as determined
// by the external traffic shaper. If the external traffic shaper is not
// handling the channel, this value will be fn.None.
Bandwidth fn.Option[lnwire.MilliSatoshi]
}
// ChannelLink is an interface which represents the subsystem for managing the // ChannelLink is an interface which represents the subsystem for managing the
// incoming htlc requests, applying the changes to the channel, and also // incoming htlc requests, applying the changes to the channel, and also

View file

@ -3443,9 +3443,13 @@ func (l *channelLink) canSendHtlc(policy models.ForwardingPolicy,
return NewLinkError(&lnwire.FailTemporaryNodeFailure{}) return NewLinkError(&lnwire.FailTemporaryNodeFailure{})
} }
auxBandwidth.WhenSome(func(bandwidth lnwire.MilliSatoshi) { if auxBandwidth.IsHandled && auxBandwidth.Bandwidth.IsSome() {
availableBandwidth = bandwidth auxBandwidth.Bandwidth.WhenSome(
}) func(bandwidth lnwire.MilliSatoshi) {
availableBandwidth = bandwidth
},
)
}
// Check to see if there is enough balance in this channel. // Check to see if there is enough balance in this channel.
if amt > availableBandwidth { if amt > availableBandwidth {
@ -3471,8 +3475,6 @@ func (l *channelLink) AuxBandwidth(amount lnwire.MilliSatoshi,
cid lnwire.ShortChannelID, htlcBlob fn.Option[tlv.Blob], cid lnwire.ShortChannelID, htlcBlob fn.Option[tlv.Blob],
ts AuxTrafficShaper) fn.Result[OptionalBandwidth] { ts AuxTrafficShaper) fn.Result[OptionalBandwidth] {
unknownBandwidth := fn.None[lnwire.MilliSatoshi]()
fundingBlob := l.FundingCustomBlob() fundingBlob := l.FundingCustomBlob()
shouldHandle, err := ts.ShouldHandleTraffic(cid, fundingBlob) shouldHandle, err := ts.ShouldHandleTraffic(cid, fundingBlob)
if err != nil { if err != nil {
@ -3486,7 +3488,9 @@ func (l *channelLink) AuxBandwidth(amount lnwire.MilliSatoshi,
// If this channel isn't handled by the aux traffic shaper, we'll return // If this channel isn't handled by the aux traffic shaper, we'll return
// early. // early.
if !shouldHandle { if !shouldHandle {
return fn.Ok(unknownBandwidth) return fn.Ok(OptionalBandwidth{
IsHandled: false,
})
} }
// Ask for a specific bandwidth to be used for the channel. // Ask for a specific bandwidth to be used for the channel.
@ -3502,7 +3506,10 @@ func (l *channelLink) AuxBandwidth(amount lnwire.MilliSatoshi,
log.Debugf("ShortChannelID=%v: aux traffic shaper reported available "+ log.Debugf("ShortChannelID=%v: aux traffic shaper reported available "+
"bandwidth: %v", cid, auxBandwidth) "bandwidth: %v", cid, auxBandwidth)
return fn.Ok(fn.Some(auxBandwidth)) return fn.Ok(OptionalBandwidth{
IsHandled: true,
Bandwidth: fn.Some(auxBandwidth),
})
} }
// Stats returns the statistics of channel link. // Stats returns the statistics of channel link.

View file

@ -976,7 +976,7 @@ func (f *mockChannelLink) AuxBandwidth(lnwire.MilliSatoshi,
lnwire.ShortChannelID, lnwire.ShortChannelID,
fn.Option[tlv.Blob], AuxTrafficShaper) fn.Result[OptionalBandwidth] { fn.Option[tlv.Blob], AuxTrafficShaper) fn.Result[OptionalBandwidth] {
return fn.Ok(fn.None[lnwire.MilliSatoshi]()) return fn.Ok(OptionalBandwidth{})
} }
var _ ChannelLink = (*mockChannelLink)(nil) var _ ChannelLink = (*mockChannelLink)(nil)

View file

@ -143,6 +143,13 @@ func (b *bandwidthManager) getBandwidth(cid lnwire.ShortChannelID,
"auxiliary bandwidth: %w", err)) "auxiliary bandwidth: %w", err))
} }
// If the external traffic shaper is not handling the
// channel, we'll just return the original bandwidth and
// no custom amount.
if !auxBandwidth.IsHandled {
return fn.Ok(bandwidthResult{})
}
// We don't know the actual HTLC amount that will be // We don't know the actual HTLC amount that will be
// sent using the custom channel. But we'll still want // sent using the custom channel. But we'll still want
// to make sure we can add another HTLC, using the // to make sure we can add another HTLC, using the
@ -152,7 +159,7 @@ func (b *bandwidthManager) getBandwidth(cid lnwire.ShortChannelID,
// the max number of HTLCs on the channel. A proper // the max number of HTLCs on the channel. A proper
// balance check is done elsewhere. // balance check is done elsewhere.
return fn.Ok(bandwidthResult{ return fn.Ok(bandwidthResult{
bandwidth: auxBandwidth, bandwidth: auxBandwidth.Bandwidth,
htlcAmount: fn.Some[lnwire.MilliSatoshi](0), htlcAmount: fn.Some[lnwire.MilliSatoshi](0),
}) })
}, },

View file

@ -904,9 +904,7 @@ func (m *mockLink) AuxBandwidth(lnwire.MilliSatoshi, lnwire.ShortChannelID,
fn.Option[tlv.Blob], fn.Option[tlv.Blob],
htlcswitch.AuxTrafficShaper) fn.Result[htlcswitch.OptionalBandwidth] { htlcswitch.AuxTrafficShaper) fn.Result[htlcswitch.OptionalBandwidth] {
return fn.Ok[htlcswitch.OptionalBandwidth]( return fn.Ok(htlcswitch.OptionalBandwidth{})
fn.None[lnwire.MilliSatoshi](),
)
} }
// EligibleToForward returns the mock's configured eligibility. // EligibleToForward returns the mock's configured eligibility.