Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ require (
github.com/lightninglabs/lightning-node-connect/hashmailrpc v1.0.2
github.com/lightninglabs/lndclient v1.0.1-0.20240725080034-64a756aa4c36
github.com/lightninglabs/neutrino/cache v1.1.2
github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240723043204-f09d4042aee4
github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240919091721-70580403898e
github.com/lightningnetwork/lnd/cert v1.2.2
github.com/lightningnetwork/lnd/clock v1.1.1
github.com/lightningnetwork/lnd/fn v1.1.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -490,8 +490,8 @@ github.com/lightninglabs/protobuf-go-hex-display v1.30.0-hex-display h1:pRdza2wl
github.com/lightninglabs/protobuf-go-hex-display v1.30.0-hex-display/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
github.com/lightningnetwork/lightning-onion v1.2.1-0.20230823005744-06182b1d7d2f h1:Pua7+5TcFEJXIIZ1I2YAUapmbcttmLj4TTi786bIi3s=
github.com/lightningnetwork/lightning-onion v1.2.1-0.20230823005744-06182b1d7d2f/go.mod h1:c0kvRShutpj3l6B9WtTsNTBUtjSmjZXbJd9ZBRQOSKI=
github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240723043204-f09d4042aee4 h1:LPnz0JxnzXJvCro714eBanzO7FKx5HF0ldU++zIu9yY=
github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240723043204-f09d4042aee4/go.mod h1:0gen58n0DVnqJJqCMN3AXNtqWRT0KltQanlvehnhCq0=
github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240919091721-70580403898e h1:Weu9TWNEIpC4XLbcUoSFK3Pv2aUSwn7NlYZKdsm8wUU=
github.com/lightningnetwork/lnd v0.18.0-beta.rc4.0.20240919091721-70580403898e/go.mod h1:/Uh0qCiU/oQls68spxpmP0kRjX/uGkLzt7P/uPpDofE=
github.com/lightningnetwork/lnd/cert v1.2.2 h1:71YK6hogeJtxSxw2teq3eGeuy4rHGKcFf0d0Uy4qBjI=
github.com/lightningnetwork/lnd/cert v1.2.2/go.mod h1:jQmFn/Ez4zhDgq2hnYSw8r35bqGVxViXhX6Cd7HXM6U=
github.com/lightningnetwork/lnd/clock v1.1.1 h1:OfR3/zcJd2RhH0RU+zX/77c0ZiOnIMsDIBjgjWdZgA0=
Expand Down
5 changes: 3 additions & 2 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -990,7 +990,8 @@ func (s *Server) HandleTraffic(cid lnwire.ShortChannelID,
//
// NOTE: This method is part of the routing.TlvTrafficShaper interface.
func (s *Server) PaymentBandwidth(htlcBlob, commitmentBlob lfn.Option[tlv.Blob],
linkBandwidth lnwire.MilliSatoshi) (lnwire.MilliSatoshi, error) {
linkBandwidth,
htlcAmt lnwire.MilliSatoshi) (lnwire.MilliSatoshi, error) {

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

return s.cfg.AuxTrafficShaper.PaymentBandwidth(
htlcBlob, commitmentBlob, linkBandwidth,
htlcBlob, commitmentBlob, linkBandwidth, htlcAmt,
)
}

Expand Down
42 changes: 40 additions & 2 deletions tapchannel/aux_traffic_shaper.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ func (s *AuxTrafficShaper) HandleTraffic(_ lnwire.ShortChannelID,
// should be handled by the traffic shaper, the HandleTraffic method should be
// called first.
func (s *AuxTrafficShaper) PaymentBandwidth(htlcBlob,
commitmentBlob lfn.Option[tlv.Blob],
linkBandwidth lnwire.MilliSatoshi) (lnwire.MilliSatoshi, error) {
commitmentBlob lfn.Option[tlv.Blob], linkBandwidth,
htlcAmt lnwire.MilliSatoshi) (lnwire.MilliSatoshi, error) {

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

// Get the minimum HTLC amount, which is just above dust.
minHtlcAmt := lnwire.NewMSatFromSatoshis(DefaultOnChainHtlcAmount)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, looking at the previous commit, I wondered if this value needed to be dynamic, based on the channel config's dust limit.
But luckily for lnd to lnd this value is always static: https://github.com/lightningnetwork/lnd/blob/b58fcf73fff36a0ac45e89fac2d7aa589fa6c47b/lnwallet/wallet.go#L1419

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, perhaps worth keeping track of somehow, in case we ever have tap channel between different LN node implementations


// LND calls this hook twice. Once to see if the overall budget of the
// node is enough, and then during pathfinding to actually see if
// there's enough balance in the channel to make the payment attempt.
//
// When doing the overall balance check, we don't know what the actual
// htlcAmt is in satoshis, so a value of 0 will be passed here. Let's at
// least check if we can afford the min amount above dust. If the actual
// htlc amount ends up being greater when calling this method during
// pathfinding, we will still check it below.

// If the passed htlcAmt is below dust, then assume the dust amount. At
// this point we know we are sending assets, so we cannot anchor them to
// dust amounts. Dust HTLCs are added to the fees and aren't
// materialized in an on-chain output, so we wouldn't have anything
// to anchor the asset commitment to.
if htlcAmt < minHtlcAmt {
htlcAmt = minHtlcAmt
}

commitment, err := cmsg.DecodeCommitment(commitmentBytes)
if err != nil {
return 0, fmt.Errorf("error decoding commitment blob: %w", err)
Expand All @@ -161,6 +183,14 @@ func (s *AuxTrafficShaper) PaymentBandwidth(htlcBlob,
// the amount.
htlcAssetAmount := htlc.Amounts.Val.Sum()
if htlcAssetAmount != 0 && htlcAssetAmount <= localBalance {
// Check if the current link bandwidth can afford sending out
// the htlc amount without dipping into the channel reserve. If
// it goes below the reserve, we report zero bandwdith as we
// cannot push the htlc amount.
if linkBandwidth < htlcAmt {
return 0, nil
}

// We signal "infinite" bandwidth by returning a very high
// value (number of Satoshis ever in existence), since we might
// not have a quote available to know what the asset amount
Expand Down Expand Up @@ -190,6 +220,14 @@ func (s *AuxTrafficShaper) PaymentBandwidth(htlcBlob,

mSatPerAssetUnit := quote.BidPrice

// At this point we have acquired what we need to express the asset
// bandwidth expressed in satoshis. Before we return the result, we need
// to check if the link bandwidth can afford sending a non-dust htlc to
// the other side.
if linkBandwidth < minHtlcAmt {
return 0, nil
}

// The available balance is the local asset unit expressed in
// milli-satoshis.
return lnwire.MilliSatoshi(localBalance) * mSatPerAssetUnit, nil
Expand Down
28 changes: 28 additions & 0 deletions tapchannel/commitment.go
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,11 @@ func CreateAllocations(chanState *channeldb.OpenChannel, ourBalance,
leaseExpiry = chanState.ThawHeight
}

dustLimit := chanState.LocalChanCfg.DustLimit
if !isOurCommit {
dustLimit = chanState.RemoteChanCfg.DustLimit
}

// The "local" and "remote" notations are always from the perspective of
// the local node. So if we want to find out the asset balance of the
// _initiator_ of the channel, we just need to take into account the
Expand Down Expand Up @@ -707,6 +712,19 @@ func CreateAllocations(chanState *channeldb.OpenChannel, ourBalance,
allocType = CommitAllocationHtlcIncoming
}

// If HTLC is dust, do not create allocation for it.
isDust := lnwallet.HtlcIsDust(
chanState.ChanType, isIncoming, isOurCommit,
filteredView.FeePerKw, htlc.Amount.ToSatoshis(),
dustLimit,
)
if isDust {
// We need to error out, as a dust HTLC carrying assets
// should not be expected.
return fmt.Errorf("error creating asset HTLC " +
"allocation, HTLC is dust")
}

allocations = append(allocations, &Allocation{
Type: allocType,
Amount: rfqmsg.Sum(htlc.AssetBalances),
Expand Down Expand Up @@ -773,6 +791,16 @@ func CreateAllocations(chanState *channeldb.OpenChannel, ourBalance,
"sibling: %w", err)
}

// If HTLC is dust, do not create allocation for it.
isDust := lnwallet.HtlcIsDust(
chanState.ChanType, isIncoming, isOurCommit,
filteredView.FeePerKw, htlc.Amount.ToSatoshis(),
dustLimit,
)
if isDust {
return nil
}

allocations = append(allocations, &Allocation{
Type: AllocationTypeNoAssets,
BtcAmount: htlc.Amount.ToSatoshis(),
Expand Down
Loading