loopout: trace logs for hasBandwidth mpp check

This commit is contained in:
Slyghtning 2024-10-14 10:24:49 +02:00
parent 8bc6b61de1
commit caa8cc850d
No known key found for this signature in database
GPG key ID: F82D456EA023C9BF
2 changed files with 61 additions and 5 deletions

View file

@ -1481,6 +1481,7 @@ func validateLoopOutRequest(ctx context.Context, lnd lndclient.LightningClient,
requiredBalance := btcutil.Amount(req.Amt + req.MaxSwapRoutingFee)
isRoutable, _ := hasBandwidth(activeChannelSet, requiredBalance,
int(maxParts))
if !isRoutable {
return 0, fmt.Errorf("%w: Requested swap amount of %d "+
"sats along with the maximum routing fee of %d sats "+
@ -1505,41 +1506,88 @@ func validateLoopOutRequest(ctx context.Context, lnd lndclient.LightningClient,
func hasBandwidth(channels []lndclient.ChannelInfo, amt btcutil.Amount,
maxParts int) (bool, int) {
scratch := make([]btcutil.Amount, len(channels))
log.Tracef("Checking if %v sats can be routed with %v parts over "+
"channel set of length %v", amt, maxParts, len(channels))
localBalances := make([]btcutil.Amount, len(channels))
var totalBandwidth btcutil.Amount
for i, channel := range channels {
scratch[i] = channel.LocalBalance
log.Tracef("Channel %v: local=%v remote=%v", channel.ChannelID,
channel.LocalBalance, channel.RemoteBalance)
localBalances[i] = channel.LocalBalance
totalBandwidth += channel.LocalBalance
}
log.Tracef("Total bandwidth: %v", totalBandwidth)
if totalBandwidth < amt {
return false, 0
}
logLocalBalances := func(shard int) {
log.Tracef("Local balances for %v shards:", shard)
for i, balance := range localBalances {
log.Tracef("Channel %v: localBalances[%v]=%v",
channels[i].ChannelID, i, balance)
}
}
split := amt
for shard := 0; shard <= maxParts; {
log.Tracef("Trying to split %v sats into %v parts", amt, shard)
paid := false
for i := 0; i < len(scratch); i++ {
if scratch[i] >= split {
scratch[i] -= split
for i := 0; i < len(localBalances); i++ {
// TODO(hieblmi): Consider channel reserves because the
// channel can't send its full local balance.
if localBalances[i] >= split {
log.Tracef("len(shards)=%v: Local channel "+
"balance %v can pay %v sats",
shard, localBalances[i], split)
localBalances[i] -= split
log.Tracef("len(shards)=%v: Subtracted "+
"%v sats from localBalance[%v]=%v",
shard, split, i, localBalances[i])
amt -= split
log.Tracef("len(shards)=%v: Remaining total "+
"amount amt=%v", shard, amt)
paid = true
shard++
break
}
}
logLocalBalances(shard)
if amt == 0 {
log.Tracef("Payment is routable with %v part(s)", shard)
return true, shard
}
if !paid {
log.Tracef("len(shards)=%v: No channel could pay %v "+
"sats, halving payment to %v and trying again",
split/2)
split /= 2
} else {
log.Tracef("len(shards)=%v: Payment was made, trying "+
"to pay remaining sats %v", shard, amt)
split = amt
}
}
log.Tracef("Payment is not routable, remaining amount that can't be "+
"sent: %v sats", amt)
logLocalBalances(maxParts)
return false, 0
}

View file

@ -12,6 +12,7 @@ import (
"github.com/lightninglabs/loop/labels"
"github.com/lightninglabs/loop/looprpc"
mock_lnd "github.com/lightninglabs/loop/test"
"github.com/lightningnetwork/lnd/build"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/routing/route"
"github.com/stretchr/testify/require"
@ -470,6 +471,13 @@ func TestValidateLoopOutRequest(t *testing.T) {
SweepConfTarget: test.confTarget,
}
log = build.NewSubLogger(
Subsystem,
genSubLogger(
build.NewRotatingLogWriter(),
interceptor,
),
)
conf, err := validateLoopOutRequest(
ctx, lnd.Client, &test.chain, req,
test.destAddr, test.maxParts,