pay: Annotate both local alias and real scid with channel hints

Debugging a number of payments showed that we sometimes waste a number
of attempts routing through a channel via its alias, rather than its
scid. This is because while we annotate the scid when it has been set,
we do not do so for the alias. The alias then is picked for routing
despite not having enough capacity, failing the attempt locally.

It can also happen that we alternate between scid and alias, doubling
the number of failed attempts before we can make progress.

This patch sets the hint for the alias to a capacity of 0 and disables
it as if the peer were offline. This means when available we'll always
use the scid, which is also far easier to read in the logs.

Changelog-Fixed: pay: We now track spendable amounts when routing on both the local alias as well as the short channel ID
This commit is contained in:
Christian Decker
2023-07-23 16:49:00 +02:00
committed by Rusty Russell
parent d25a8ca0fd
commit 2549dd6ea5

View File

@@ -2360,7 +2360,6 @@ local_channel_hints_listpeerchannels(struct command *cmd, const char *buffer,
chans = json_to_listpeers_channels(tmpctx, buffer, toks);
for (size_t i = 0; i < tal_count(chans); i++) {
struct short_channel_id scid;
bool enabled;
u16 htlc_budget;
@@ -2369,11 +2368,6 @@ local_channel_hints_listpeerchannels(struct command *cmd, const char *buffer,
* state. */
enabled = chans[i]->connected && streq(chans[i]->state, "CHANNELD_NORMAL");
if (chans[i]->scid != NULL)
scid = *chans[i]->scid;
else
scid = *chans[i]->alias[LOCAL];
/* Take the configured number of max_htlcs and
* subtract any HTLCs that might already be added to
* the channel. This is a best effort estimate and
@@ -2384,8 +2378,28 @@ local_channel_hints_listpeerchannels(struct command *cmd, const char *buffer,
else
htlc_budget = chans[i]->max_accepted_htlcs - chans[i]->num_htlcs;
channel_hints_update(p, scid, chans[i]->direction, enabled, true,
&chans[i]->spendable_msat, &htlc_budget);
/* If we have both a scid and a local alias we want to
* use the scid, and mark the alias as
* unusable. Otherwise `getroute` might return the
* alias, which we resolve correctly, but our
* channel_hints would be off after updates, since
* we'd only ever update one of the aliases. Causing
* the other to be considered usable.
*/
if (chans[i]->scid != NULL) {
channel_hints_update(
p, *chans[i]->scid, chans[i]->direction, enabled,
true, &chans[i]->spendable_msat, &htlc_budget);
channel_hints_update(p, *chans[i]->alias[LOCAL],
chans[i]->direction,
false /* not enabled */, true,
&AMOUNT_MSAT(0), &htlc_budget);
} else {
channel_hints_update(p, *chans[i]->alias[LOCAL],
chans[i]->direction, enabled, true,
&chans[i]->spendable_msat,
&htlc_budget);
}
}
payment_continue(p);