Skip to content

Commit a6f5c3e

Browse files
committed
tapchannel: add chan reserve check on PaymentBandwidth method
1 parent ece0f83 commit a6f5c3e

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

server.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -990,7 +990,8 @@ func (s *Server) HandleTraffic(cid lnwire.ShortChannelID,
990990
//
991991
// NOTE: This method is part of the routing.TlvTrafficShaper interface.
992992
func (s *Server) PaymentBandwidth(htlcBlob, commitmentBlob lfn.Option[tlv.Blob],
993-
linkBandwidth lnwire.MilliSatoshi) (lnwire.MilliSatoshi, error) {
993+
linkBandwidth,
994+
htlcAmt lnwire.MilliSatoshi) (lnwire.MilliSatoshi, error) {
994995

995996
srvrLog.Debugf("PaymentBandwidth called, htlcBlob=%v, "+
996997
"commitmentBlob=%v", spew.Sdump(htlcBlob),
@@ -1001,7 +1002,7 @@ func (s *Server) PaymentBandwidth(htlcBlob, commitmentBlob lfn.Option[tlv.Blob],
10011002
}
10021003

10031004
return s.cfg.AuxTrafficShaper.PaymentBandwidth(
1004-
htlcBlob, commitmentBlob, linkBandwidth,
1005+
htlcBlob, commitmentBlob, linkBandwidth, htlcAmt,
10051006
)
10061007
}
10071008

tapchannel/aux_traffic_shaper.go

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ func (s *AuxTrafficShaper) HandleTraffic(_ lnwire.ShortChannelID,
120120
// should be handled by the traffic shaper, the HandleTraffic method should be
121121
// called first.
122122
func (s *AuxTrafficShaper) PaymentBandwidth(htlcBlob,
123-
commitmentBlob lfn.Option[tlv.Blob],
124-
linkBandwidth lnwire.MilliSatoshi) (lnwire.MilliSatoshi, error) {
123+
commitmentBlob lfn.Option[tlv.Blob], linkBandwidth,
124+
htlcAmt lnwire.MilliSatoshi) (lnwire.MilliSatoshi, error) {
125125

126126
// If the commitment or HTLC blob is not set, we don't have any
127127
// information about the channel and cannot determine the available
@@ -140,6 +140,28 @@ func (s *AuxTrafficShaper) PaymentBandwidth(htlcBlob,
140140
return linkBandwidth, nil
141141
}
142142

143+
// Get the minimum HTLC amount, which is just above dust.
144+
minHtlcAmt := lnwire.NewMSatFromSatoshis(DefaultOnChainHtlcAmount)
145+
146+
// LND calls this hook twice. Once to see if the overall budget of the
147+
// node is enough, and then during pathfinding to actually see if
148+
// there's enough balance in the channel to make the payment attempt.
149+
//
150+
// When doing the overall balance check, we don't know what the actual
151+
// htlcAmt is in satoshis, so a value of 0 will be passed here. Let's at
152+
// least check if we can afford the min amount above dust. If the actual
153+
// htlc amount ends up being greater when calling this method during
154+
// pathfinding, we will still check it below.
155+
156+
// If the passed htlcAmt is below dust, then assume the dust amount. At
157+
// this point we know we are sending assets, so we cannot anchor them to
158+
// dust amounts. Dust HTLCs are added to the fees and aren't
159+
// materialized in an on-chain output, so we wouldn't have anything
160+
// to anchor the asset commitment to.
161+
if htlcAmt < minHtlcAmt {
162+
htlcAmt = minHtlcAmt
163+
}
164+
143165
commitment, err := cmsg.DecodeCommitment(commitmentBytes)
144166
if err != nil {
145167
return 0, fmt.Errorf("error decoding commitment blob: %w", err)
@@ -161,6 +183,14 @@ func (s *AuxTrafficShaper) PaymentBandwidth(htlcBlob,
161183
// the amount.
162184
htlcAssetAmount := htlc.Amounts.Val.Sum()
163185
if htlcAssetAmount != 0 && htlcAssetAmount <= localBalance {
186+
// Check if the current link bandwidth can afford sending out
187+
// the htlc amount without dipping into the channel reserve. If
188+
// it goes below the reserve, we report zero bandwdith as we
189+
// cannot push the htlc amount.
190+
if linkBandwidth < htlcAmt {
191+
return 0, nil
192+
}
193+
164194
// We signal "infinite" bandwidth by returning a very high
165195
// value (number of Satoshis ever in existence), since we might
166196
// not have a quote available to know what the asset amount
@@ -190,6 +220,14 @@ func (s *AuxTrafficShaper) PaymentBandwidth(htlcBlob,
190220

191221
mSatPerAssetUnit := quote.BidPrice
192222

223+
// At this point we have acquired what we need to express the asset
224+
// bandwidth expressed in satoshis. Before we return the result, we need
225+
// to check if the link bandwidth can afford sending a non-dust htlc to
226+
// the other side.
227+
if linkBandwidth < minHtlcAmt {
228+
return 0, nil
229+
}
230+
193231
// The available balance is the local asset unit expressed in
194232
// milli-satoshis.
195233
return lnwire.MilliSatoshi(localBalance) * mSatPerAssetUnit, nil

0 commit comments

Comments
 (0)