Merge pull request #9687 from GeorgeTsagk/aux-trff-shpr-htlcview

`AuxTrafficShaper.PaymentBandwidth` uses HTLC view
This commit is contained in:
Oliver Gugger authored and GitHub committed 2025-04-17 07:59:00 +02:00
commit 7381f4b221
6 files changed
+69 -15

No files matched your search

+3 -2
View File
@@ -10,6 +10,7 @@ import (
"github.com/lightningnetwork/lnd/graph/db/models" "github.com/lightningnetwork/lnd/graph/db/models"
"github.com/lightningnetwork/lnd/invoices" "github.com/lightningnetwork/lnd/invoices"
"github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/lightningnetwork/lnd/lnwallet/chainfee"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/record"
@@ -516,8 +517,8 @@ type AuxTrafficShaper interface {
// is a custom channel that should be handled by the traffic shaper, the // is a custom channel that should be handled by the traffic shaper, the
// ShouldHandleTraffic method should be called first. // ShouldHandleTraffic method should be called first.
PaymentBandwidth(htlcBlob, commitmentBlob fn.Option[tlv.Blob], PaymentBandwidth(htlcBlob, commitmentBlob fn.Option[tlv.Blob],
linkBandwidth, linkBandwidth, htlcAmt lnwire.MilliSatoshi,
htlcAmt lnwire.MilliSatoshi) (lnwire.MilliSatoshi, error) htlcView lnwallet.AuxHtlcView) (lnwire.MilliSatoshi, error)
// IsCustomHTLC returns true if the HTLC carries the set of relevant // IsCustomHTLC returns true if the HTLC carries the set of relevant
// custom records to put it under the purview of the traffic shaper, // custom records to put it under the purview of the traffic shaper,
+1
View File
@@ -3505,6 +3505,7 @@ func (l *channelLink) AuxBandwidth(amount lnwire.MilliSatoshi,
commitmentBlob := l.CommitmentCustomBlob() commitmentBlob := l.CommitmentCustomBlob()
auxBandwidth, err := ts.PaymentBandwidth( auxBandwidth, err := ts.PaymentBandwidth(
htlcBlob, commitmentBlob, l.Bandwidth(), amount, htlcBlob, commitmentBlob, l.Bandwidth(), amount,
l.channel.FetchLatestAuxHTLCView(),
) )
if err != nil { if err != nil {
return fn.Err[OptionalBandwidth](fmt.Errorf("failed to get "+ return fn.Err[OptionalBandwidth](fmt.Errorf("failed to get "+
+13 -12
View File
@@ -133,7 +133,7 @@ type CommitDiffAuxInput struct {
// UnfilteredView is the unfiltered, original HTLC view of the channel. // UnfilteredView is the unfiltered, original HTLC view of the channel.
// Unfiltered in this context means that the view contains all HTLCs, // Unfiltered in this context means that the view contains all HTLCs,
// including the canceled ones. // including the canceled ones.
UnfilteredView *HtlcView UnfilteredView AuxHtlcView
// WhoseCommit denotes whose commitment transaction we are computing the // WhoseCommit denotes whose commitment transaction we are computing the
// diff for. // diff for.
@@ -177,9 +177,8 @@ type AuxLeafStore interface {
// correspond to the passed aux blob, and an existing channel // correspond to the passed aux blob, and an existing channel
// commitment. // commitment.
FetchLeavesFromCommit(chanState AuxChanState, FetchLeavesFromCommit(chanState AuxChanState,
commit channeldb.ChannelCommitment, commit channeldb.ChannelCommitment, keyRing CommitmentKeyRing,
keyRing CommitmentKeyRing, whoseCommit lntypes.ChannelParty, whoseCommit lntypes.ChannelParty) fn.Result[CommitDiffAuxResult]
) fn.Result[CommitDiffAuxResult]
// FetchLeavesFromRevocation attempts to fetch the auxiliary leaves // FetchLeavesFromRevocation attempts to fetch the auxiliary leaves
// from a channel revocation that stores balance + blob information. // from a channel revocation that stores balance + blob information.
@@ -206,7 +205,7 @@ func auxLeavesFromView(leafStore AuxLeafStore, chanState *channeldb.OpenChannel,
return leafStore.FetchLeavesFromView(CommitDiffAuxInput{ return leafStore.FetchLeavesFromView(CommitDiffAuxInput{
ChannelState: NewAuxChanState(chanState), ChannelState: NewAuxChanState(chanState),
PrevBlob: blob, PrevBlob: blob,
UnfilteredView: originalView, UnfilteredView: newAuxHtlcView(originalView),
WhoseCommit: whoseCommit, WhoseCommit: whoseCommit,
OurBalance: ourBalance, OurBalance: ourBalance,
TheirBalance: theirBalance, TheirBalance: theirBalance,
@@ -227,13 +226,15 @@ func updateAuxBlob(leafStore AuxLeafStore, chanState *channeldb.OpenChannel,
return fn.MapOptionZ( return fn.MapOptionZ(
prevBlob, func(blob tlv.Blob) fn.Result[fn.Option[tlv.Blob]] { prevBlob, func(blob tlv.Blob) fn.Result[fn.Option[tlv.Blob]] {
return leafStore.ApplyHtlcView(CommitDiffAuxInput{ return leafStore.ApplyHtlcView(CommitDiffAuxInput{
ChannelState: NewAuxChanState(chanState), ChannelState: NewAuxChanState(chanState),
PrevBlob: blob, PrevBlob: blob,
UnfilteredView: nextViewUnfiltered, UnfilteredView: newAuxHtlcView(
WhoseCommit: whoseCommit, nextViewUnfiltered,
OurBalance: ourBalance, ),
TheirBalance: theirBalance, WhoseCommit: whoseCommit,
KeyRing: keyRing, OurBalance: ourBalance,
TheirBalance: theirBalance,
KeyRing: keyRing,
}) })
}, },
) )
+35
View File
@@ -5,6 +5,7 @@ import (
"github.com/lightningnetwork/lnd/fn/v2" "github.com/lightningnetwork/lnd/fn/v2"
"github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/tlv" "github.com/lightningnetwork/lnd/tlv"
) )
@@ -13,6 +14,37 @@ import (
// signatures within the custom data for an existing HTLC. // signatures within the custom data for an existing HTLC.
var htlcCustomSigType tlv.TlvType65543 var htlcCustomSigType tlv.TlvType65543
// AuxHtlcView is a struct that contains a safe copy of an HTLC view that can
// be used by aux components.
type AuxHtlcView struct {
// NextHeight is the height of the commitment transaction that will be
// created using this view.
NextHeight uint64
// Updates is a Dual of the Local and Remote HTLCs.
Updates lntypes.Dual[[]AuxHtlcDescriptor]
// FeePerKw is the fee rate in sat/kw of the commitment transaction.
FeePerKw chainfee.SatPerKWeight
}
// newAuxHtlcView creates a new safe copy of the HTLC view that can be used by
// aux components.
//
// NOTE: This function should only be called while holding the channel's read
// lock, since the underlying local/remote payment descriptors are accessed
// directly.
func newAuxHtlcView(v *HtlcView) AuxHtlcView {
return AuxHtlcView{
NextHeight: v.NextHeight,
Updates: lntypes.Dual[[]AuxHtlcDescriptor]{
Local: fn.Map(v.Updates.Local, newAuxHtlcDescriptor),
Remote: fn.Map(v.Updates.Remote, newAuxHtlcDescriptor),
},
FeePerKw: v.FeePerKw,
}
}
// AuxHtlcDescriptor is a struct that contains the information needed to sign or // AuxHtlcDescriptor is a struct that contains the information needed to sign or
// verify an HTLC for custom channels. // verify an HTLC for custom channels.
type AuxHtlcDescriptor struct { type AuxHtlcDescriptor struct {
@@ -99,6 +131,9 @@ func (a *AuxHtlcDescriptor) RemoveHeight(
// newAuxHtlcDescriptor creates a new AuxHtlcDescriptor from a payment // newAuxHtlcDescriptor creates a new AuxHtlcDescriptor from a payment
// descriptor. // descriptor.
//
// NOTE: This function should only be called while holding the channel's read
// lock, since the underlying payment descriptors are accessed directly.
func newAuxHtlcDescriptor(p *paymentDescriptor) AuxHtlcDescriptor { func newAuxHtlcDescriptor(p *paymentDescriptor) AuxHtlcDescriptor {
return AuxHtlcDescriptor{ return AuxHtlcDescriptor{
ChanID: p.ChanID, ChanID: p.ChanID,
+14
View File
@@ -2704,6 +2704,20 @@ func (v *HtlcView) AuxTheirUpdates() []AuxHtlcDescriptor {
return fn.Map(v.Updates.Remote, newAuxHtlcDescriptor) return fn.Map(v.Updates.Remote, newAuxHtlcDescriptor)
} }
// FetchLatestAuxHTLCView returns the latest HTLC view of the lightning channel
// as a safe copy that can be used outside the wallet code in concurrent access.
func (lc *LightningChannel) FetchLatestAuxHTLCView() AuxHtlcView {
// This read lock is important, because we access both the local and
// remote log indexes as well as the underlying payment descriptors of
// the HTLCs when creating the view.
lc.RLock()
defer lc.RUnlock()
return newAuxHtlcView(lc.fetchHTLCView(
lc.updateLogs.Remote.logIndex, lc.updateLogs.Local.logIndex,
))
}
// fetchHTLCView returns all the candidate HTLC updates which should be // fetchHTLCView returns all the candidate HTLC updates which should be
// considered for inclusion within a commitment based on the passed HTLC log // considered for inclusion within a commitment based on the passed HTLC log
// indexes. // indexes.
+3 -1
View File
@@ -7,6 +7,7 @@ import (
"github.com/go-errors/errors" "github.com/go-errors/errors"
"github.com/lightningnetwork/lnd/fn/v2" "github.com/lightningnetwork/lnd/fn/v2"
"github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/tlv" "github.com/lightningnetwork/lnd/tlv"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@@ -150,7 +151,8 @@ func (*mockTrafficShaper) ShouldHandleTraffic(_ lnwire.ShortChannelID,
// is a custom channel that should be handled by the traffic shaper, the // is a custom channel that should be handled by the traffic shaper, the
// HandleTraffic method should be called first. // HandleTraffic method should be called first.
func (*mockTrafficShaper) PaymentBandwidth(_, _ fn.Option[tlv.Blob], func (*mockTrafficShaper) PaymentBandwidth(_, _ fn.Option[tlv.Blob],
linkBandwidth, _ lnwire.MilliSatoshi) (lnwire.MilliSatoshi, error) { linkBandwidth, _ lnwire.MilliSatoshi,
_ lnwallet.AuxHtlcView) (lnwire.MilliSatoshi, error) {
return linkBandwidth, nil return linkBandwidth, nil
} }